diff --git a/runcoms/README.md b/runcoms/README.md index 9df890e5..cc8a4e35 100644 --- a/runcoms/README.md +++ b/runcoms/README.md @@ -10,61 +10,199 @@ in */etc* by default. User-local configuration files have the same name as their global counterparts but are prefixed with a dot (hidden). Zsh looks for these files in the path -stored in the `$ZDOTDIR` environmental variable. However, if said variable is -not defined, Zsh will use the user's home directory. +stored in the `$ZDOTDIR` environment variable. However, if said variable is +not defined, Zsh will use the user's home directory. This is found on the +config scripts as `${ZDOTDIR:-$HOME}` and is a `zsh` idiomatic way of doing +something like this: -File Descriptions ------------------ - -The configuration files are read in the following order: - 01. /etc/zshenv - 02. ~/.zshenv - 03. /etc/zprofile - 04. ~/.zprofile - 05. /etc/zshrc - 06. ~/.zshrc - 07. ~/.zpreztorc - 08. /etc/zlogin - 09. ~/.zlogin - 10. ~/.zlogout - 11. /etc/zlogout +```bash +if [[ -n $ZDOTDIR ]]; then + DOTFILES_PATH=$ZDOTDIR +else + DOTFILES_PATH=$HOME +fi +source $DOTFILES_PATH/.zshenv -### zshenv +#pro tip! set $ZDOTDIR on /etc/zshenv to ~/.zconf to have all runcoms live there instead of cluttering ~ =) +``` +the above is the same as: `source ${ZDOTDIR:-$HOME}/.zshenv` is equivalent to: -This file is sourced by all instances of Zsh, and thus, it should be kept as -small as possible and should only define environment variables. -### zprofile +Sourcing of these confguration files depends mostly on 2 things: -This file is similar to zlogin, but it is sourced before zshrc. It was added -for [KornShell][1] fans. See the description of zlogin below for what it may -contain. +1. Whether you are running a *login shell* +2. Whether the `RCS` and `GLOBAL_RCS` options are set. They are usually + set by default -zprofile and zlogin are not meant to be used concurrently but can be done so. -### zshrc +File Descriptions +----------------- -This file is sourced by interactive shells. It should define aliases, -functions, shell options, and key bindings. -### zpreztorc +| always runs | when `GLOBAL_RCS` is set | when `RCS` is set | Purpose | stuff that usually goes there, and notes | +|------------------|-----------------------------------------|-----------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `/etc/zshenv` | | | system provided minimal environment | Always runs! should be minimal set ZDOTDIR, minimal environment. system paths +| | | `${ZDOTDIR:-$HOME}/.zshenv` | user environment overrides non-interactive, non-login shells (when invoked via shebang in a script or via `zsh -c [script]` or when invoked by `make` | personal environment overrides, such as `MANPATH`, `TERM`, `fpath` *non interactive scripts should have their environment completly set up here* ) +| | `/etc/zshprofile` | | system profile for login shells (`zsh -ls zsh - or via _ssh forced command_`) | minimal system paths for remote interaction, site `fpath`, site `$LOCALE`, lang. +| | | `${ZDOTDIR:-$HOME}/.zshprofile` | personal preferences for interactive login shells | your preferred `$LOCALE`, `$LANG`, `readlne` config, `cdpath`, session managers, additional `fpath` ) login shells (but non necessarily **ineractive** as when invoked via _ssh remote cmd_ ) will read config up to this point +| | `/etc/zshrc` | | system provided startup script, for interactive shells, (local shells that live in an `XTerm`, `URxvt`, `gnome-terminal`) or subshells (like running `xterm` from the command prompt of a _login xterm_, | site login accounting, security monitors, site command logging policy +| | | `${ZDOTDIR:-$HOME}/.zshrc` | user customization of their *interactive* environment for terminals | sourcing custom completions (`gcloud.comp.inc`), custom user frameworks (zprezto is invoked here), additional path required by custom software installed in `/opt/*` +| | `/etc/zshlogin` | | additional customization for interactive **login** shells, such as those accessed via ssh | tmux attach to existing session +| | | `${ZDOTDIR:-$HOME}/.zshlogin` | user script for *login shell startup* (this shell is a session leader, and allocates a `ptty` | aliases, keybindings, personal startup programs, time tracking apps, session managers, quote of the day, fortunes +| .. | ... your shell session happens here ... | +| | | `${ZDOTDIR:-$HOME}/.zshlogout` | personal cleanup tasks | setting personal `crontabs` or `at` tasks, logging checout to your time tracking software, fortune to say goodbye. +| `/etc/zshlogout` | | | site cleanup tasks | site command logging policy stop, login accounting records, security context spindown, etcThe configuration files are read in the following order: + +Discussion +---------- + +There are several places to add personal configuration and preferences in +the files already provided for startup, it’s just a matter of placing them +in the appropriate place. Most of them should probably go in +`${ZDOTDIR:-$HOME}/.zshrc` **before** invoking zprezto init, to choose +the modules that should get loaded, and using the appropriate `zstyle` +calls form preferences (`zstyle` is a kind of _registry_ for shell configuration +native to `zsh`) + + +Any tweaks to prezto’s behavior should go **after** invoking zprezto init +in `zshrc` or, in `${ZDOTDIR:-$HOME}/.zlogin` . Note however that the +`zlogin` (sysem or user) files will be sourced **only for login shells**. + +That means, when logging in to a remote system via ssh for example or +when calling say, `XTerm` or your favorite emulator by specifying you +want a **login** shell (by calling `zsh -ls` instead of plain `zsh`). +Otherwise, the `zlogin` files are ignored. + +Also, note that another difference between interactive login shells and +plain interactive shells, is that, besides sourcing `zlogin` files, +interactive login shells also allocate a pseudo-tty (you can see them when +invoking `w`. Login shells have a pty assigned, while interactive non-login +shells don't.) + +Why is this designed this way? because login shells are assumed to be +the main point of interaction with a user while non login shells would +be spawned as _sub-shells_ of a *login shell* , when executing scripts +that call `zsh` as a command interpreter, for example, when the *shebang* is +`#!/usr/bin/env zsh` or equivalent. + +When launching a new terminal within an *X11* session, it is safe to +assume that you are *already logged in* so any terminal emulator will +launch an *interactive-non-login* shell. Which is, _per specification_ +the correct behavior, but not the behavior most users *expect*. + + +There is a reason for this _specified_ behaviour: `zlogin` files should +be used for *interaction oriented settings* such as custom completion, +keybindings, `tmux` session setup, and most `alias`es. + +The advantage of grouping all interaction oriented settings in +`.zlogin` is that non-interactive shells (executing scripts via +`zsh -c [script]`, the *shebang*, subshells or `make` invoked shells, +for example) will not be burdened by additional config settings making +them faster and more responsive, as _keybindings_ and _aliases_ are not +even loaded at startup, after all, an _executable non-interactive script_, +should never call on keybindings or aliases (assuming they were properly +written to be portable) + + +Finally, it is a common source of frustration amongst graphical environment +users, to spend some time adding their customizations to `.zlogin` only +to see them ignored when launching a new `XTerm` or `tmux` pane. + +This can be solved by calling (or aliasing) your terminal emulator with +the required option to invoke a *login* shell, for `XTerm`, for example +you would call `xterm -e zsh -ls` on tmux you may add one of the following +lines to your `.tmux.conf`: + +```config +#tmux.conf: + + set -g default-command 'exec /usr/bin/zsh -ls' #this will make zsh a login shell AND a session leader + set -g default-shell '/usr/bin/zsh -ls' +``` + +Here is an examplefor *i3wm* on ubuntu +```bash + +#i3wm.conf: + ... + set $XTERM_CMD='xterm -e zsh -ls` + bind $mod+x $XTERM_CMD + ... +``` +if you want to replace your non-login shell on your emulator with a brand-new +shiny *login* shell you can issue `exec zsh -ls` at your command prompt. +Doing this, however **will not write that terminal’s history to file** unless +`INC_APPEND_HISTORY` was set when you strted the shell + +`INC_APPEND_HISTORY` makes `zsh` append history entries as soon as the +command is finished. *zprezto* helpfuly sets `INC_APPEND_HISTORY`, +`INC_APPEND_HISTORY_TIME`, and `SHARE_HISTORY` which makes your history +available immediately from different terminals on command completion, +and records execution time on the history file. Pretty neat, huh?) + +You could tack-on all interactive customizations on `zshrc` but you will +end up with bloated shells on non-interactive environments. Perhaps desktop +workstation users will not notice any difference, but in resource-constrained +environments it may be significant in terms of execution time and energy +consumption (v.gr when running a Raspberry PI on batteries or on a cell +phone environment such as `termux`) + +You may be thinking... why is `zpreztorc` not invoked on `.zlogin` instead +of `.zshrc`? I believe it was a wise design decision, in order to +eliminate complexity by having the whole of *prezto* configured and +launched from a single point, as some of the modules need to be sourced +early in the startup process, `editor` and `gnu-utls` come to mind. +If invoked later on the startup, such as would be the case in `.zlogin` +would makee it easier to conflict with stuff users may add on `zshrc`. +Also, it avoids **not being loaded** and causing user frustration if +the user launches *non-login shells* from graphical environments, as +discussed above. + +## Conclusion + +For customization of your environment, use your `.zshrc` after zprezto +has been invoked, or before to remove or activate packages via `zstyle` +calls + + or + +use `.zshlogin` to override or tweak zprezto behavior. there is also +`.zpreztorc` but you may want to leave that one alone. + +In any case, this question is often brought up by users that use the +distributed *runcoms* **as is** which is a terrible idea, since doing +`git pull` to update your distribution will clobber your customizations. + +it’s a better idea to *copy* the distributed *runcoms* to your `$ZDOTDIR` a +nd merge any changes an update may bring, if any (they are usually +confined to `.zpreztorc`) + -This file configures Prezto. -### zlogin +Troubleshooting +--------------- + +1. if prezto and some of your settings are loaded, but others are not; +make sure you are running an *interactive login shell* (you should have +a tty allocated, visible on the `w` list) and the `$TTY` variable should +be set, if that is not the case, check the above discussion, you can +'replace' your shell _in situ_ by issuing the command `exec zsh -l` -This file is sourced by login shells after zshrc, and thus, it should contain -commands that need to execute at login. It is usually used for messages such as -[fortune][2], [msgs][3], or for the creation of files. -This is not the file to define aliases, functions, shell options, and key -bindings. It should not change the shell environment. +2. if you notice that none of your settings are loaded, check that +`/etc/zshenv` does not disable them. In any case + +```bash +setopt global_rcs +setopt rcs +``` + +in `/etc/zshenv` should set them both. This issue would be extremely rare. -### zlogout -This file is sourced by login shells during logout. It should be used for -displaying messages and the deletion of files. Authors -------