Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: Rewrite of zsh-newuser-install (Mikael's subthread)



> On 5. Apr 2021, at 22.44, Mikael Magnusson <mikachu@xxxxxxxxx> wrote:
> 
> On 4/5/21, Marlon Richert <marlon.richert@xxxxxxxxx> wrote:
>> #
>> # 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.

Sure, I can move it to an autoloadable function. That’s fine by me. I did not come up with the -l, though. Earlier in the thread, Oliver & Bart didn’t like using `exec zsh` and offered this instead. See [48031](https://www.zsh.org/mla/workers/2021/msg00244.html). I’d be happy to change it, but I don’t know how they feel about it.


>> 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.

Personally, I would’ve preferred `setopt HIST_IGNORE_ALL_DUPS SHARE_HISTORY`, but there were several votes against that earlier in this thread.


>> # 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.

They change the default widgets bound to up/down, which makes for more elegant code, since we don’t have to deal with app vs raw mode.


>> # 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.

Sure, I can make it do just delete.


>> # 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.

I would expect Tab to insert the current selection, not insert an “unambiguous” prefix or _just do nothing_ when such a prefix doesn’t exist. However, I don’t want to override the defaults when I can avoid it. So, that’s why I added Backtab to do what, since that actually doesn’t have any function by default; not in the ZLE and not in complist’s `interactive` mode.

Also, in complist’s `interactive` mode, Tab does _not_ cycle forward, but inserts “unambiguous". Ergo, in this context, I would _not_ expect to Backtab to cycle backwards.


>> #   * 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).

`interactive` means it’s not actual menu selection, though. Instead, it enables type-ahead completion, which is an extremely useful complist feature.


>> 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).

Sadly, without using _generic, it’s not possible to enable or disable menu selection on an individual widget basis. That’s why I filed [48194](https://www.zsh.org/mla/workers/2021/msg00407.html). I, too, would prefer this code not to go into the .zshrc file.


> 
>> bindkey -M menuselect -s "$key[Backtab]" "$key[Return]$key[Tab]"
> 
> How is this different from ^[a (eg, accept-and-hold) in menu selection?

accept-and-hold doesn’t work correctly with, for example, directory completions. To see this for yourself, try `cd /` + Tab + ^[a. Then try `cd /` + Tab + Backtab. Notice the difference. The first one makes no sense.


>> 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?

These are complist features. It does what it says in the comments: vi-backward-blank-word moves to the previous completion group in the completion menu; vi-forward-blank-word moves to the next  completion group in the completion menu.


>> # 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?

Only when there is an “unambiguous” prefix that can be inserted. But I guess since we use `interactive` complist, this isn’t really necessary. I will remove it.


>> 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...

No, I’m just creating two handy, generic widgets here. Using the completion system for it is just an implementation detail. But I can move those, too, into an autoloadable function; no problem.


>> 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

Sure, I’ll add.


>> # 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.

It makes the shell pick up in the same dir as where you left off last time. I would hardly call that surprising. In fact, I would pretty much call that _expected_ for most applications nowadays.


>> ##
>> # 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.

Sure, I can make that comment longer. There was already a remark about that earlier. I just prefer to keep everything as concise as possible. Usability research teaches us that the more text there is, the less likely anyone will read it.


>> # 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?

Because it’s familiar from the GUI world: If text looks selected, then you expect it to be replaced when you type over it.


>> # 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

There’s no harm in it, though, is there? Plus it makes it so you Don’t Repeat Yourself. Now you have only variable you need to change when you want to move from `less` to, say, `bat`.


On 6. Apr 2021, at 0.01, Mikael Magnusson <mikachu@xxxxxxxxx> wrote:
> 
> On 4/5/21, Mikael Magnusson <mikachu@xxxxxxxxx> wrote:
>>> bindkey "$key[Backtab]" reverse-menu-complete
>>> bindkey -M menuselect -s "$key[Backtab]" "$key[Return]$key[Tab]"
> 
> Also just noticed you have both of these, so if you press shift-tab
> twice it will first do a reverse-menu-complete inserting the last
> match, then if you press it again it accepts it and inserts the first
> match.

Yeah, perhaps those two don’t really make sense together. I would like there to be a completion menu shortcut that inserts the current selection and then immediately completes again, but that doesn’t really rhyme with reverse-menu-complete.





Messages sorted by: Reverse Date, Date, Thread, Author