Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: Rewrite of zsh-newuser-install (Mikael's subthread)
- X-seq: zsh-workers 48406
- From: Mikael Magnusson <mikachu@xxxxxxxxx>
- To: Marlon Richert <marlon.richert@xxxxxxxxx>
- Cc: Zsh hackers list <zsh-workers@xxxxxxx>
- Subject: Re: Rewrite of zsh-newuser-install (Mikael's subthread)
- Date: Mon, 5 Apr 2021 21:44:16 +0200
- Archived-at: <https://zsh.org/workers/48406>
- Archived-at: <http://www.zsh.org/sympa/arcsearch_id/zsh-workers/2021-04/CAHYJk3Sh8ErYyObh%3DnURosOnj4%2BbsB1WsxhOi_-e%3Dn_1fjAQ6Q%40mail.gmail.com>
- List-id: <zsh-workers.zsh.org>
On 4/5/21, Marlon Richert <marlon.richert@xxxxxxxxx> wrote:
> On Thu, Mar 25, 2021 at 3:15 AM Daniel Shahaf <d.s@xxxxxxxxxxxxxxxxxx>
> wrote:
> I got replies so far from openSUSE and Fedora, and made some minor
> changes based on their feedback:
> https://gitlab.com/marlonrichert/zsh-sensible/-/commit/b111f20b14891af4a385b3867fe690dc8281fe8f
I didn't look at this before, so I'll have a go now...
> #
> # Type `zrestart` to safely apply changes after editing this file.
> #
> zrestart() {
> local zshrc=${ZDOTDIR:-$HOME}/.zshrc
> print -P "Validating %U$zshrc%u..."
> zsh -nf $zshrc ||
> return
>
> print -P 'Restarting Zsh...'
> zsh -l &&
> exit
> }
This could be an autoloadable function, not pasted verbatim in .zshrc.
Also disagree with -l here. You can use $options[login] or $- to see
if you're in a login shell already and start same. Things like this we
can't fix after users already copy this config. It should try to
mostly be configuration, not helper functions that can have permanent
flaws once installed.
> ##
> # History settings
> # See http://zsh.sourceforge.net/Doc/Release/Parameters.html#Parameters-Used-By-The-Shell
> # and http://zsh.sourceforge.net/Doc/Release/Options.html#History
> #
>
> # File in which to save command line history
> HISTFILE=${ZDOTDIR:-$HOME}/.zhistory
>
> SAVEHIST=10000 # Max number of history lines to save to file
> HISTSIZE=$(( 1.2 * SAVEHIST )) # Max number of history lines to keep in memory
> setopt EXTENDED_HISTORY # Save each command's time & duration to history.
> setopt INC_APPEND_HISTORY_TIME # Save history whenever a command finishes, not just on shell exit.
> setopt HIST_EXPIRE_DUPS_FIRST # Delete duplicate history lines first, when running out of space.
> setopt HIST_IGNORE_DUPS # Don't store last command line if identical to previous one.
ok, I don't agree with the dups settings but they're changeable easily.
> ##
> # Prompt settings
> # See http://zsh.sourceforge.net/Doc/Release/Prompt-Expansion.html#Expansion-of-Prompt-Sequences
> # and http://zsh.sourceforge.net/Doc/Release/Parameters.html#Parameters-Used-By-The-Shell
> #
[snip]
This is 70 lines that should be a prompt theme, not pasted verbatim in .zshrc.
> ##
> # Key bindings
> # See http://zsh.sourceforge.net/Doc/Release/Zsh-Line-Editor.html#Zle-Builtins
> #
>
> bindkey -e # Use `emacs` as the main keymap.
> typeset -A key # Declare `$key` table, without overriding any existing values.
How could $key possibly already exist as an associative array at this
point? The shell just started so it could at most be a scalar from the
environment in which case you did just override it.
> # Check if the terminal supports setting application mode.
> zmodload zsh/terminfo
> autoload -Uz add-zle-hook-widget
> if [[ -n "$terminfo[smkx]" ]]; then
> # Enable application mode, so we can use terminfo codes.
> add-zle-hook-widget line-init .zshrc.app-mode; .zshrc.app-mode() { echoti smkx }
> if [[ -n "$terminfo[rmkx]" ]]; then
> add-zle-hook-widget line-finish .zshrc.raw-mode; .zshrc.raw-mode() { echoti rmkx }
> fi
>
> # Assign each value only if it has not been defined earlier.
> : ${key[Up]:=$terminfo[kcuu1]} ${key[Down]:=$terminfo[kcud1]}
> : ${key[Right]:=$terminfo[kcuf1]} ${key[Left]:=$terminfo[kcub1]}
> : ${key[End]:=$terminfo[kend]} ${key[Home]:=$terminfo[khome]}
> : ${key[PageUp]:=$terminfo[kpp]} ${key[PageDown]:=$terminfo[knp]}
> : ${key[Return]:=$terminfo[cr]} ${key[Delete]:=$terminfo[kdch1]}
> : ${key[Tab]:=$terminfo[ht]} ${key[Backtab]:=${terminfo[kcbt]:-$terminfo[cbt]}}
> fi
>
> # Fill in any remaining blank values with common defaults.
> : ${key[Up]:='^[[A'} ${key[Down]:='^[[B'} ${key[Right]:='^[[C'} ${key[Left]:='^[[D'}
> : ${key[End]:='^[[F'} ${key[Home]:='^[[H'} ${key[PageUp]:='^[[5~'} ${key[PageDown]:='^[[6~'}
> : ${key[Return]:='\r'} ${key[Delete]:='^[[3~'} ${key[Tab]:='^I'} ${key[Backtab]:='^[[Z'}
All of the above can be simple assignments given the previous comment.
I also personally don't like the smkx stuff but I guess that's just my
opinion not a criticism. It means you can't just look at what a
keycode is by using cat to make a keybind.
> # Alt-H: Open `man` page of current command.
> unalias run-help 2>/dev/null; autoload -Uz run-help{,-git,-ip,-openssl,-p4,-sudo,-svk,-svn}
>
> # Alt-Shift-/: Show definition of current command.
> unalias which-command 2>/dev/null; autoload -Uz which-command; zle -N which-command
>
> bindkey '^Z' undo # Control-Z
> bindkey '^[^Z' redo # Alt-Control-Z
>
> # Up/Down: Cycle through history lines that start with same word as command line.
> zle -A up-line-or-{search,history}
> zle -A down-line-or-{search,history}
These two lines don't actually bind any keys, but the comment claims they do.
> # Alt-Right/Left: Move cursor right/left one word.
> bindkey "^[$key[Right]" forward-word
> zle -A {emacs-,}forward-word
> bindkey "^[$key[Left]" backward-word
> zle -A {emacs-,}backward-word
> WORDCHARS='' # Characters treated as part of words (in addition to letters & numbers)
Why are we setting WORDCHARS to the empty string here?
> bindkey "$key[Home]" beginning-of-line
> bindkey "$key[End]" end-of-line
>
> # Delete: Delete one character to the right or, if that's not possible, list completions.
> # If the list is too long to fit on screen, then start type-ahead search.
> bindkey "$key[Delete]" delete-char-or-list
> zle -C {,.}delete-char-or-list _generic
> zstyle ':completion:delete-char-or-list:*:default' menu yes select=long-list interactive
This is a very unintuitive keybind, I realize that ctrl-d does this,
but I would never expect the delete key to do it. Also see later
comment about menu selection being force enabled.
> # Alt-Delete: Cut the word to the right of the cursor. (opposite of Alt-Backspace)
> bindkey "^[$key[Delete]" kill-word
>
> bindkey '^U' backward-kill-line # Control-U: Cut text to beginning of line.
ok
> ##
> # Completion settings
> # See http://zsh.sourceforge.net/Doc/Release/Completion-System.html#Standard-Styles
> #
>
> ZLE_REMOVE_SUFFIX_CHARS=$' \t\n;' # Characters that remove completion suffixes.
> ZLE_SPACE_SUFFIX_CHARS=$'&|' # Characters that instead replace them with a space.
> LISTMAX=0 # Immediately list completions whenever they fit on screen.
> unsetopt LIST_AMBIGUOUS # Always list completions when there is more than one match.
> unsetopt LIST_BEEP # Don't beep when listing completions.
> setopt LIST_PACKED # Lay out completions as compactly as possible.
ok
> # Initialize the completion system.
> # See http://zsh.sourceforge.net/Doc/Release/Completion-System.html#Use-of-compinit
> # and http://zsh.sourceforge.net/Doc/Release/Zsh-Modules.html#The-zsh_002fcomplist-Module
> zmodload zsh/complist
> autoload -Uz compinit
> compinit -d ${ZDOTDIR:-$HOME}/.zcompdump
>
> # Enable completion caching & store cache files in a sensible place.
> zstyle ':completion:*' cache-path ${ZDOTDIR:-$HOME}/.zcompcache
> zstyle ':completion:*' use-cache yes
>
> # Tab/Shift-Tab: Start type-ahead completion.
> # * Tab: Insert substring shown by `interactive: <prefix>[]<suffix>`.
> # * Shift-Tab: Accept selection & start next completion.
Would never expect shift-tab to do anything else than reverse order completion.
> # * Arrow keys: Change selection.
> # * Enter: Accept selection & stop completing.
> zstyle ':completion:(|reverse-)menu-complete:*:default' menu yes select interactive
I don't agree with enabling menu selection by default, but maybe just
because I hate menu selection... It should at any rate be made clearer
how to disable it (in all places).
> bindkey "$key[Tab]" menu-complete
> zle -C {,.}menu-complete _generic
> bindkey "$key[Backtab]" reverse-menu-complete
> zle -C {,.}reverse-menu-complete _generic
I don't think that a "newbie friendly .zshrc" is the place to start
changing the default handler of completion widgets. Also all of these
{,.} everywhere should probably have some explanatory comment, it's
not obvious what those lines are even for (I know, of course, but I
had to think about it... So probably not obvious to a newbie).
> bindkey -M menuselect -s "$key[Backtab]" "$key[Return]$key[Tab]"
How is this different from ^[a (eg, accept-and-hold) in menu selection?
> bindkey -M menuselect "^[$key[Up]" vi-backward-blank-word # Alt-Up: Previous completion group
> bindkey -M menuselect "^[$key[Down]" vi-forward-blank-word # Alt-Down: Next completion group
So we set WORDCHARS to the empty string, then use the vi widgets
anyway for good measure?
> bindkey -M menuselect "$key[PageUp]" backward-word # Page Up
> bindkey -M menuselect "$key[PageDown]" forward-word # Page Down
I think most people expect these keys to scroll history backward/forwards.
> # Try these completers in order until one of them succeeds:
> # _oldlist: try to reuse previous completions
> # _expand: try to substitute expansions (See http://zsh.sourceforge.net/Doc/Release/Expansion.html)
> # _complete: try regular completions
> # _correct: try _complete with spelling correction
> # _complete:-fuzzy: try _complete with a fuzzy matcher
> # _history: try history words
> # _ignored: show completions that have been hidden so far
> zstyle ':completion:*' completer \
> _oldlist _expand _complete _correct _complete:-fuzzy _history _ignored
>
> # (Shift-)Tab uses old list, if visible.
> zstyle ':completion:(|reverse-)menu-complete:*' old-list shown
> zstyle ':completion:*' old-list never # Other widgets always generate new completions.
>
> # Even when _expand succeeds, if there was only one choice, continue to the next completer.
> zstyle ':completion:*:expand:*' accept-exact continue
>
> zstyle ':completion:*' remove-all-dups yes # Hide duplicate history words.
ok
> # Each 'string in quotes' is tried in order until one them succeeds.
> # r:|[.]=** does .bar -> foo.bar
> # r:?|[-_]=** does f-b -> foo-bar and F_B -> FOO_BAR
> # l:?|=[-_] does foobar -> foo-bar and FOOBAR -> FOO_BAR
> # m:{[:lower:]-}={[:upper:]_} does foo-bar -> FOO_BAR (but not vice versa)
> # r:|?=** does fbr -> foo-bar and bar -> foo-bar
> zstyle ':completion:*:complete:*' matcher-list \
> 'r:|[.]=** r:?|[-_]=** l:?|=[-_] m:{[:lower:]-}={[:upper:]_}'
> zstyle ':completion:*:complete-fuzzy:*' matcher-list \
> 'r:|?=** m:{[:lower:]}={[:upper:]}'
> zstyle ':completion:*:options' matcher 'b:-=+' # For options, do -x -> +x
possibly a bit magic but ok.
> # Hide certain completions, unless we get no other completions.
> zstyle ':completion:*' prefix-needed yes # Params & functions starting with `.` or `_`
> zstyle ':completion:*:users' ignored-patterns '_*' # Users starting with `_`
>
> zstyle ':completion:*' group-name '' # Organize completions in groups.
> zstyle ':completion:*:descriptions' format '%B%d%b' # Show group titles in bold.
> zstyle ':completion:*:expansions' format "%B%d%b for '%o'"
> zstyle ':completion:*:corrections' format '%B%d%b for %F{red}%o%f (%e typo(s))'
> zstyle ':completion:*' list-dirs-first yes # Group dirs separately from other files.
> zstyle ':completion:*' separate-sections yes # Show `man` and `dict` sections.
> zstyle ':completion:*' insert-sections yes # Insert `man` sections.
> zstyle ':completion:*:default' list-prompt '' # Enable completion list scrolling.
>
> # Add color to messages and warnings.
> zstyle ':completion:*:messages' format "%F{r}%d%f"
> zstyle ':completion:*:warnings' format '%F{r}No %d found.%f'
>
> # Initialize `$color` table.
> autoload -Uz colors
> colors
> unfunction colors
it's too bad show-ambiguity needs this because otherwise colors is
largely depracated by "new" prompt codes so this part is a bit
confusing perhaps.
> # Highlight next differentiating character.
> zstyle ':completion:*:default' show-ambiguity "$color[black];$color[bg-yellow]"
I disagree with using this, it disables colored filetypes doesn't it?
> zstyle ':completion:*' list-separator '' # Eliminate some false positives.
> # Reuse $LS_COLORS for completion highlighting and add additional colors.
> # See http://zsh.sourceforge.net/Doc/Release/Zsh-Modules.html#Colored-completion-listings
> # zstyle -e: Evaluate the given code each time this style gets checked.
> # See end of section http://zsh.sourceforge.net/Doc/Release/Completion-System.html#Overview-1
> zstyle -e ':completion:*:default' list-colors .zshrc.list-colors
> .zshrc.list-colors() {
> reply=(
> ${(s.:.)LS_COLORS}
> "ma=$color[bold];$color[white];$color[bg-blue]" # Menu selection
> "sa=$color[green];$color[underline]" # Suffix aliases
> "(global-aliases|parameters)=*=$color[cyan]"
> "(aliases|executables|functions|commands|builtins|jobs)=*=$color[green]"
> "(reserved-words)=*=$color[yellow];$color[bg-black]"
> "(glob(flags|quals)|modifiers)=*=$color[blue]"
> )
> }
ok
> ##
> # Directory settings
> # See http://zsh.sourceforge.net/Doc/Release/Options.html#Changing-Directories
> #
>
> setopt AUTO_CD # Change dirs simply by typing a dir name. No `cd` required.
> setopt AUTO_PUSHD # Auto-store each dir we visit in the dir stack.
> setopt PUSHD_SILENT # Don't print the dir stack when using `pushd`.
> setopt PUSHD_IGNORE_DUPS # Discard duplicate entries.
>
> bindkey -s '^[-' "^Qpushd -1$key[Return]" # Alt-Minus: Back to previous dir stack entry.
> bindkey -s '^[=' "^Qpushd +0$key[Return]" # Alt-Equals: Forward to next dir stack entry.
Might go as far as say NAK on these bindkey -s abominations.
> setopt PUSHD_MINUS # `~-` + Tab: Select a dir stack entry.
> bindkey -s "^[$key[Up]" "^Q..$key[Return]" # Alt-Up: Up to parent dir.
> bindkey "^[$key[Down]" menu-select # Alt-Down: Select a local dir or file.
> zle -C {,}menu-select _generic
More random default completion widgets changing even though we are
long done with completion settings...
> zstyle ':completion:menu-select:*:default' menu yes select interactive
Another place to find for a poor user who wants to disable menu selection...
> zstyle ':completion:menu-select:*:-command-:*' tag-order \
> 'globbed-files executables (|local-)directories suffix-aliases' -
> zstyle ':completion:menu-select:*' tag-order '(|*-)directories (|*-)files' -
these two need comments
> # Auto-save last 20 dirs to file whenever we change dirs.
> # See http://zsh.sourceforge.net/Doc/Release/User-Contributions.html#Recent-Directories
> autoload -Uz add-zsh-hook chpwd_recent_dirs
> add-zsh-hook chpwd chpwd_recent_dirs
> zstyle ':chpwd:*' recent-dirs-file ${ZDOTDIR:-$HOME}/.chpwd-recent-dirs
>
> # On startup, initialize dir stack from file.
> autoload -Uz chpwd_recent_filehandler
> chpwd_recent_filehandler
> cd $reply[1]
> dirs $reply[@] >/dev/null
Does this start zsh in some other directory than it inherited from the
terminal? If so, nak from me on that, way too surprising.
> ##
> # Miscellaneous shell options
> # See http://zsh.sourceforge.net/Doc/Release/Options.html
> #
>
> setopt GLOB_STAR_SHORT # Use `**` for recursive globbing; `***` to also traverse symlinks.
** and *** already exist without this option, confusingly phrased.
> setopt NUMERIC_GLOB_SORT # Sort numeric matches numerically, not lexicographically.
> setopt EXTENDED_GLOB # Enable additional pattern matching operators.
> # See http://zsh.sourceforge.net/Doc/Release/Expansion.html#Filename-Generation
>
> unsetopt CLOBBER # Don't let `>` overwrite files. Use `>|` instead.
> setopt INTERACTIVE_COMMENTS # Allow comments on the command line.
ok
> ##
> # Other settings
> #
>
> # Make each entry in these Unique (that is, remove duplicates).
> # See http://zsh.sourceforge.net/Doc/Release/Shell-Builtin-Commands.html#index-typeset
> typeset -gU PATH path FPATH fpath CDPATH cdpath MANPATH manpath
specifying the scalar halves of these tied variables is superfluous.
> # Add some basic command line highlighting.
> # See http://zsh.sourceforge.net/Doc/Release/Zsh-Line-Editor.html#Character-Highlighting
> zle_highlight=(
> isearch:fg=black,bg=yellow # Matched search text
> paste:none # Yanked/pasted text
> region:bg=blue # Selected text
> special:fg=cyan,bold # Unprintable characters
> suffix:bg=blue # Auto-removable suffix inserted by completion
> )
There are many colors, why use the same for the region and the suffix?
> # Use suffix aliases to associate file extensions with commands.
> # This way, you can open a file simply by typing its name.
> # See http://zsh.sourceforge.net/Doc/Release/Shell-Builtin-Commands.html#index-alias
> READNULLCMD='less' # Makes `< foo` do `less < foo`.
> alias -s txt='<' md='<' # .txt and .md files
> alias -s log='tail -f' # .log files
Letting the user type < for less is one thing, but you don't really
save anything by using a shorter command in the rhs of an alias... it
does doesn't allow the user to type more than one filename. eg:
% < file1 file2
zsh: command not found: file2
% less file1 file2
file1 (file 1 of 2) lines ?-?/? (END) - Next: file2
Overall I think there's a bit too much stuff in here. It's longer than
some (many) actual personal .zshrc files I've seen.
--
Mikael Magnusson
Messages sorted by:
Reverse Date,
Date,
Thread,
Author