Shell Share your .zshrc file

ILUXA

Aspiring Daemon

Reaction score: 490
Messages: 728

  1. Install it # pkg ins -y shells/zsh.
  2. Set it as your login shell # chsh -s /usr/local/bin/zsh your_user_name.
  3. Relogin.
I like the way how tcsh works, but it is outdated a little bit (only 1 update since 2012), also some nice features are available in zsh, like suggesting flags and other completions for cli and not only cli apps… But some of its features are distracting and annoying IMHO. I didn't find any tcsh-like configuration for zsh, so I tried to create my own zshrc, to make zsh work as close as possible to tcsh. Zsh will list directory content when you press tab if no text or only spaces are located before cursor (_nice_autolist function in config), also it completes words that are before cursor only, it doesn't remove slashes automatically, doesn't use a menu... Also many other improvements present and few my custom functions.

Code:
# if user is not root, start tmux with shell
#[[ $UID -ne 0 && ! $TMUX ]] && exec tmux

# autologout when no commands were entered for 60 min.
#export TMOUT=3600

export EDITOR=vim PAGER=less LESS="-giAMR" CLICOLOR=1
export LS_COLORS='di=32:ln=35:so=33:pi=31:ex=34:bd=34;40:cd=35;40:su=30;42:sg=37;42:tw=30;46:ow=31;46'
export LSCOLORS=cxfxdxbxexeafaachcagbg

PROMPT='%(1j.%j.) %B%F{green}%C %b%f%# '
HISTFILE=$HOME/.zhistory
HISTSIZE=100000
SAVEHIST=100000
LISTMAX=999

setopt notify                   # report the status of background jobs immediately
setopt correct                  # try to correct the spelling of commands
setopt auto_cd                  # if the command is the name of a directory, perform cd
setopt auto_list                # automatically list choices on an ambiguous completion
setopt auto_continue            # unsuspend suspended jobs on "disown" command
setopt chase_links              # resolve symlink to its real value when cd into it
setopt append_history           # append history to the history file, rather than replace it
setopt inc_append_history       # history lines are added to the $HISTFILE as soon as they are entered
setopt extended_history         # save command beginning timestamp and the duration
setopt hist_reduce_blanks       # remove superfluous blanks from history
setopt hist_ignore_dups         # do not save history line if it duplicates previous history event
setopt hist_ignore_all_dups     # if new command duplicates an older one, remove the older from history
setopt hist_expire_dups_first   # when delete duplicates in history, delete oldest history event
setopt hist_save_no_dups        # when writing history, older commands that duplicate newer ones are omitted
setopt hist_ignore_space        # do not save line to the history list when first character is a space
setopt hist_verify              # perform history expansion and reload the line into the editing buffer
#setopt share_history           # share history between all sessions
setopt rec_exact                # recognize exact matches even if they are ambiguous
setopt auto_pushd               # cd push the old directory onto the directory stack
setopt pushd_ignore_dups        # don't push multiple copies of the same directory onto the directory stack
setopt pushd_silent             # do not print the directory stack after pushd or popd
setopt check_jobs               # report the status of jobs before exiting
setopt long_list_jobs           # list jobs in long format by default
setopt glob_complete            # do not insert all the words resulting from the wildcard expansion
setopt extended_glob            # treat the "#", "~" and "^" characters as part of patterns
setopt csh_null_glob            # report an error when all the patterns in a command have no matches
#unsetopt bad_pattern           # disable "bad pattern" error
#unsetopt nomatch               # do not show an error when using glob without quotes
unsetopt hup                    # do not kill running jobs when shell exits
unsetopt auto_remove_slash      # disable automatic removing of slash
unsetopt auto_menu              # do not use menu completion
unsetopt check_running_jobs     # complain only about suspended jobs on exit
#unsetopt list_types            # don't show file trailing identifying mark (@,*...)
unsetopt beep                   # disable beep
[[ $UID -eq 0 ]] && setopt dot_glob # when logged in as root, completion uses dotfiles

autoload -Uz compinit; compinit
autoload -U select-word-style; select-word-style b
zstyle ':completion:*' use-cache true
zstyle ':completion:*' cache-path ~/.zsh/
#zstyle ':completion:*' users iluxa root test
zstyle ':completion:*' accept-exact '*(N)'
zstyle ':completion:*' accept-exact-dirs true
zstyle ':completion:*' squeeze-slashes true
zstyle ':completion:*' file-sort links reverse
zstyle ':completion:*' list-colors ${(s.:.)LS_COLORS}
zstyle ':completion:*' completer _expand _complete _files  _expand_alias _correct _approximate
zstyle ':completion:*' matcher-list '' 'm:{[:lower:][:upper:]}={[:upper:][:lower:]}'
zstyle ':completion:*:cd:*' tag-order local-directories directory-stack path-directories
zstyle ':completion:*:commands' rehash true
zstyle ':completion:*:functions' ignored-patterns '_*'
zstyle ':completion:*:*:*:*:processes' command 'ps -U $USER -o pid,%mem,user,start,command -w'
zstyle ':zle:*' word-chars '*?_-[]~'
zstyle ':zle:*kill-word' word-chars '*?_-.[]~'

# select emacs keymap
bindkey -e
# alt+z/shift+alt+z
bindkey '\ez' undo
bindkey '\eZ' redo
# del key
bindkey '\e[3~' delete-char
# alt+del
bindkey '\e[3;3~' kill-word
# alt+left/right
bindkey '\e[1;3D' backward-kill-word
bindkey '\e[1;3C' kill-word
# alt+up/down
bindkey '\e[1;3A' backward-kill-line
bindkey '\e[1;3B' kill-line
# ctrl+left/right
bindkey '\e[1;5D' backward-word
bindkey '\e[1;5C' forward-word
# ctrl+up/down
bindkey '\e[1;5A' beginning-of-line
bindkey '\e[1;5B' end-of-line
# end/home
bindkey '\e[1~' beginning-of-line
bindkey '\e[4~' end-of-line
bindkey '\e[H' beginning-of-line
bindkey '\e[F' end-of-line
# up/down to autocomplete from history, moving cursor to end of line
autoload -U history-search-end
zle -N history-beginning-search-backward-end history-search-end
zle -N history-beginning-search-forward-end history-search-end
bindkey '\e[A' history-beginning-search-backward-end
bindkey '\e[B' history-beginning-search-forward-end
bindkey '\eOA' history-beginning-search-backward-end
bindkey '\eOB' history-beginning-search-forward-end
# ctrl+alt+up/down to search history
bindkey '\e[1;7A' history-incremental-search-backward
bindkey '\e[1;7B' history-incremental-search-forward
# ctrl+alt+left/right to mo move cursor using different "word-chars"
bindkey '\e[1;7C' emacs-forward-word
bindkey '\e[1;7D' emacs-backward-word
# shift+tab - reverse menu
bindkey '\e[Z' reverse-menu-complete
# disable alt+x
bindkey -r '\ex'

# list dir with TAB, when there are only spaces/no text
# before cursor, or complete text, that is before cursor only
_nice_autolist() { if [[ ${LBUFFER// } ]]
        then zle expand-or-complete
        else BUFFER=ls\  CURSOR=3 zle list-choices
        zle end-of-list; fi }
zle -N _nice_autolist
bindkey '\CI' _nice_autolist

# ctrl+b - return to previous dir
_back() { pushd +1 && zle reset-prompt && zle -M "dirs: `dirs`" }
zle -N _back
bindkey '\Cb' _back

# ctrl+f - resume job
_foreground() { CURSOR=0 LBUFFER+=' fg %' && zle accept-line }
zle -N _foreground
bindkey '\CF' _foreground

# ctrl+r - update shell history
_read_hist() { fc -R && zle -M 'history updated' }
zle -N _read_hist
bindkey '\CR' _read_hist

# ctrl+u - go to upper dir
_go_up() { cd .. && zle reset-prompt && zle -M "pwd: $PWD" }
zle -N _go_up
bindkey '\CU' _go_up

# alt+h - last 30 history lines
_last_hist() { zle -M "`fc -rld -30`"}
zle -N _last_hist
bindkey "\eh" _last_hist

# alt+j - list jobs
_list_jobs() { zle -M "`jobs -l`"}
zle -N _list_jobs
bindkey "\ej" _list_jobs

# ctrl+del - delete character from beginning of line
_del_first_char() { CURSOR=0 zle delete-char }
zle -N _del_first_char
bindkey "\e[3;5~" _del_first_char

# alt+c - copy current line to X CLIPBOARD (x11/xclip required)
_xclipcopy() { if [[ ${DISPLAY+X} && ${BUFFER// } ]]
        then print -rn -- $BUFFER | xclip -i -selection c
        zle -M "\"$BUFFER\" saved to X CLIPBOARD"; fi }
zle -N _xclipcopy
bindkey "\ec" _xclipcopy

# alias -es
#alias -g @@='| grep -i --color'
#alias -g '^^'="| $PAGER"
#alias -g '%#'='| wc -l'
#alias -g %+='| tee -a'
#alias -g %%='| sort'
#alias -g %%-='| head'
#alias -g %%_='| tail'
#alias -g %%cp='| xclip -i -selection c'
alias -g ...='../../'
alias -g ....='../../../'
alias -g .....='../../../../'
alias .='pwd'
alias c='cat'
alias r='readlink -f'
alias history='fc -l -E 1'
alias l='less'
alias f='find'
alias d='diff'
alias e='builtin echo'
alias t='touch'
alias ls='ls -F'
alias la='ls -a'
alias ll='ls -lht'
alias rm='rm -I'
alias grep='grep --color'
alias g='grep -i'
alias v='vim'
alias du='du -h'
alias mkdir='mkdir -p'
alias stat='stat -x'
When you'll press TAB once, current directory content will appear below prompt,
if you'll press TAB twice, current dir content will be displayed above prompt.
To move completion suggestions above prompt when current line isn't empty,
just press HOME key and press TAB.
 
Last edited:
OP
ILUXA

ILUXA

Aspiring Daemon

Reaction score: 490
Messages: 728

I mean versions, previous version was released in 2012, new version appear when FreeBSD-11.0-RELEASE was released(6.20 as far as I remember, cannot test it now because I'm writing from phone.)

Also there were no improvements or new features in new 6.20 version, only bug fixes.
 
Last edited:
OP
ILUXA

ILUXA

Aspiring Daemon

Reaction score: 490
Messages: 728

Here is also nice zsh prompt, which I use
Code:
PROMPT='%(1j.%j.) %B%F{green}%C %f%b%# '
It shows your current directory name, and also,
if you got background jobs, it shows the count of background jobs.


To suspend current job, use ctrl+z,
to resume % fg %<job number>,
to move job to background % bg %<job number>
and to disown job % disown %<job number>.
If "setopt auto_continue" is present in your ~/.zshrc, then jobs
will be automatically moved to background on % disown command.
(Replace "<job number>" with number of your job (for example % bg %2),
to list all jobs, use % jobs command, also it is possible to use job name,
for example % fg %vim\ file. Or use % disown <press TAB>,
zsh completion will allow you to select job name.)
 
Last edited:
OP
ILUXA

ILUXA

Aspiring Daemon

Reaction score: 490
Messages: 728

Here is my few zsh functions, which I really like, first one
returns to previous dir and shows output of % dirs command,
second one changes your current dir to upper dir and shows $PWD:
Code:
# ctrl+b - return to previous dir
_back() { pushd +1 2>/dev/null
        zle reset-prompt
        zle -M "dirs: `dirs -l`" }
zle -N _back; bindkey '\CB' _back

# ctrl+u - go to upper dir
_go_up() { cd ..
        zle reset-prompt 
        zle -M "pwd: $PWD" }
zle -N _go_up; bindkey '\CU' _go_up

# completion ignores _* functions
zstyle ':completion:*:functions' ignored-patterns '_*'
 
Last edited:
OP
ILUXA

ILUXA

Aspiring Daemon

Reaction score: 490
Messages: 728

If you use vi mode in zsh shell, it is possible to synchronize zsh cut buffer with X PRIMARY selection (shift+insert/middle click), using custom function. I took this function from here and added few improvements, originally it had to add zsh cut buffer to X CLIPBOARD, but it is annoying a little bit, especially if you're using some clipboard managers, like clipit. Also it used to add new line to all copied text, but I've added builtin print -rn command, which solved the issue. First, it checks if X is running. (x11/xclip installation is required.) Here it is:
Code:
# synchronize vi mode cut buffer with X PRIMARY selection
if [[ ${DISPLAY+X} ]]; then
_X-PRIMARY-widgets() {
        local copy_or_paste=$1; shift
        for widget in $@; do
        if [[ $copy_or_paste = copy ]]
        then eval "_X-PRIMARY-$widget() {
        zle .$widget; print -rn -- \$CUTBUFFER | xclip }"
        else eval "_X-PRIMARY-$widget() {
        CUTBUFFER=\$(xclip -o 2>/dev/null); zle .$widget }"; fi
        zle -N $widget _X-PRIMARY-$widget; done }
local copy_widgets=(vi-yank{,-eol} vi-delete vi-{change,yank}-whole-line)
local paste_widgets=(vi-put-{before,after})
_X-PRIMARY-widgets copy $copy_widgets
_X-PRIMARY-widgets paste  $paste_widgets
fi

To use vi mode with zsh, add this to your zshrc file:
Code:
# select vi keymap
bindkey -v

Here is also useful function for usage with zsh shell in vi mode.
It shows indicator in right prompt when in insert mode.

If user is root, then it'll be in red color,
otherwise it'll use green color, useful for global /etc/zshrc file.
Code:
# indicate insert mode in right prompt
setopt transient_rprompt; RPROMPT=
zle-line-init zle-keymap-select() {
        if [[ $KEYMAP = vicmd ]]; then RPROMPT=
        else RPROMPT="%B%F{%(!.red.green)}-- INSERT --%f%b"
        fi; RPROMPT2=$RPROMPT; zle reset-prompt }
zle -N zle-line-init; zle -N zle-keymap-select
It is possible to use the same code for changing prompt (PS1) color for root/user in /etc/zshrc as well:
Code:
PROMPT="%(1j.%j.) %B%F{%(!.red.green)}%C%f %#%b "

To copy current line to X CLIPBOARD in insert/command modes, I'm using this function:
Code:
# shift+alt+c - add current line to X CLIPBOARD
_xclipcopyline() {
        if [[ ${BUFFER// } ]]
        then print -rn -- $BUFFER | xclip -sel c
        zle -M "\"$BUFFER\" saved to X CLIPBOARD"; fi }
zle -N _xclipcopyline; bindkey '\eC' _xclipcopyline; bindkey -a '\eC' _xclipcopyline
It's possible to use ctrl+v to paste selected with mouse text (works like shift+insert)
Code:
# ctrl+v - paste from PRIMARY selection
_xclippaste() { LBUFFER+="`xclip -o`" }
zle -N _xclippaste; bindkey '\CV' _xclippaste
This is what I'm using to update current title
Code:
# update titles
# show current dir with 2 parent dirs
# and '#' if user is root or '%' oterwise
precmd() { print -n "\e]0;${PWD#${PWD%/*/*/*}/} ${${UID/#0/\#}/$UID/\%}\a" }
Снимок экрана от 2020-03-26 08-19-07.png

Снимок экрана от 2020-03-26 08-18-37.png


I'm using this with sysutils/tmux, with setting titles to "#T" (default shell titles) in tmux.conf.
Session number: shell title (current tab number/session tabs count):
Code:
set -g set-titles on
set -g set-titles-string "#S: #T (#I/#{session_windows})"
Снимок экрана от 2020-03-26 09-00-22.png

To change titles when using your custom zsh functions, precmd should be added to function, e.g.
Code:
# ctrl+b - return to previous dir
_back() { pushd +1 2>/dev/null
        zle reset-prompt
        zle -M "dirs: `dirs -l`"
        precmd }
zle -N _back; bindkey '\CB' _back
 
Last edited:
Top