Skip to content

Instantly share code, notes, and snippets.

@ivan
Last active April 23, 2023 17:03
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save ivan/79de5e87210e8cf21e305bb4c30c4360 to your computer and use it in GitHub Desktop.
Save ivan/79de5e87210e8cf21e305bb4c30c4360 to your computer and use it in GitHub Desktop.
#!/bin/zsh
# This is meant to be sourced; shebang line is for editors
umask 027
# Let me type a ! in a filename without escaping it
set +o histexpand
# http://www.zsh.org/mla/workers/1996/msg00615.html
HISTSIZE=21000
SAVEHIST=20000
mkdir -p ~/.config/zsh
touch ~/.config/zsh/history
HISTFILE=~/.config/zsh/history
# inlined eval "$(dircolors -b)", modified to remove most bold '01'.
# bold text makes CJK and even English harder to read, especially when
# using a narrow font like PragmataPro Mono.
#
# This LS_COLORS is also used by the :completion: setup below
export LS_COLORS="rs=0:\
di=34:\
ln=36:\
mh=00:\
pi=40;33:\
so=01;35:\
bd=40;33;01:\
cd=40;33;01:\
or=40;31;01:\
mi=00:\
su=37;41:\
sg=30;43:\
ca=30;41:\
tw=30;42:\
ow=34;42:\
st=37;44:\
ex=01;32:\
*.tar=31:\
*.tgz=31:\
*.arc=31:\
*.arj=31:\
*.taz=31:\
*.lha=31:\
*.lz4=31:\
*.lzh=31:\
*.lzma=31:\
*.tlz=31:\
*.txz=31:\
*.tzo=31:\
*.t7z=31:\
*.zip=31:\
*.z=31:\
*.Z=31:\
*.dz=31:\
*.gz=31:\
*.lrz=31:\
*.lz=31:\
*.lzo=31:\
*.xz=31:\
*.bz2=31:\
*.bz=31:\
*.tbz=31:\
*.tbz2=31:\
*.tz=31:\
*.deb=31:\
*.rpm=31:\
*.jar=31:\
*.war=31:\
*.ear=31:\
*.sar=31:\
*.rar=31:\
*.alz=31:\
*.ace=31:\
*.zoo=31:\
*.cpio=31:\
*.7z=31:\
*.rz=31:\
*.cab=31:\
*.jpg=35:\
*.jpeg=35:\
*.gif=35:\
*.bmp=35:\
*.pbm=35:\
*.pgm=35:\
*.ppm=35:\
*.tga=35:\
*.xbm=35:\
*.xpm=35:\
*.tif=35:\
*.tiff=35:\
*.png=35:\
*.svg=35:\
*.svgz=35:\
*.mng=35:\
*.pcx=35:\
*.mov=35:\
*.mpg=35:\
*.mpeg=35:\
*.m2v=35:\
*.mkv=35:\
*.webm=35:\
*.ogm=35:\
*.mp4=35:\
*.m4v=35:\
*.mp4v=35:\
*.vob=35:\
*.qt=35:\
*.nuv=35:\
*.wmv=35:\
*.asf=35:\
*.rm=35:\
*.rmvb=35:\
*.flc=35:\
*.avi=35:\
*.fli=35:\
*.flv=35:\
*.gl=35:\
*.dl=35:\
*.xcf=35:\
*.xwd=35:\
*.yuv=35:\
*.cgm=35:\
*.emf=35:\
*.ogv=35:\
*.ogx=35:\
*.aac=00;36:\
*.au=00;36:\
*.flac=00;36:\
*.m4a=00;36:\
*.mid=00;36:\
*.midi=00;36:\
*.mka=00;36:\
*.mp3=00;36:\
*.mpc=00;36:\
*.ogg=00;36:\
*.ra=00;36:\
*.wav=00;36:\
*.oga=00;36:\
*.opus=00;36:\
*.spx=00;36:\
*.xspf=00;36"
# Use modern completion system
autoload -Uz compinit
compinit
# Use emacs keybindings even if our EDITOR is set to vi
bindkey -e
# Make ctrl-backspace delete a whole word
bindkey '^H' backward-kill-word
# Use a character list that makes backward-kill-word match text editors
WORDCHARS='_'
# Don't require typing the 'cd ' to change directory
setopt autocd
# Prevent commands from entering history when preceded by a space
setopt hist_ignore_space
# Append commands to history immediately so that they show up in new shells
setopt inc_append_history
# Ignore "# comments" typed or pasted into an interactive shell
setopt interactivecomments
### Mostly essential stock settings from /etc/zsh/newuser.zshrc.recommended
zstyle ':completion:*' auto-description 'specify: %d'
zstyle ':completion:*' completer _expand _complete _correct _approximate
zstyle ':completion:*' format 'Completing %d'
zstyle ':completion:*' group-name ''
zstyle ':completion:*' menu select=2
zstyle ':completion:*:default' list-colors ${(s.:.)LS_COLORS}
zstyle ':completion:*' list-colors ''
zstyle ':completion:*' list-prompt %SAt %p: Hit TAB for more, or the character to insert%s
zstyle ':completion:*' matcher-list '' 'm:{[:lower:][:upper:]}={[:upper:][:lower:]}' '+l:|=* r:|=*'
zstyle ':completion:*' select-prompt %SScrolling active: current selection at %p%s
zstyle ':completion:*' use-compctl false
zstyle ':completion:*' verbose true
zstyle ':completion:*:*:kill:*:processes' list-colors '=(#b) #([0-9]#)*=0=01;31'
zstyle ':completion:*:kill:*' command 'ps -u $USER -o pid,%cpu,tty,cputime,cmd'
# Don't exclude dotfiles when tab-completing
_comp_options+=(globdots)
### Terminal title configuration
# precmd is run before the prompt is displayed
precmd() {
# Set the terminal title to 'hostname# pwd'
print -Pn '\e]0;%m# %~\a'
}
# preexec is run after you hit Enter, but before the command is run
preexec() {
# Set the terminal title to 'hostname# the command being run'
#
# See http://www.zsh.org/mla/users/2004/msg00948.html
# "Re: question about quoting % in preexec" to understand
# the escaping strategy here.
print -Pn '\e]0;%m# '
# Truncate to 80 characters to work around a bug in konsole that
# causes the terminal to stop updating when setting a long title:
# https://bugs.kde.org/show_bug.cgi?id=415463
print -rn -- "${1:0:80}"
print -Pn '\a'
}
### Helper functions for prompt
fast-cat() {
echo -E "$(< $1)"
}
print-git-branch() {
if [[ -f ".git/HEAD" ]]; then
echo -E ":${$(fast-cat .git/HEAD)#ref: refs/heads/}"
fi
}
### System-wide environment
setopt promptsubst # needed for \$ evaluation
# PS1=EXITSTATUS USER@HOST:PWD:GIT_BRANCH#
# The exit status is padded with spaces on the left so that it is at least three characters.
PS1="\
$(print '%{\e[0;33m%}')\${(l:3:: :)?} \
$(print '%{\e[1;31m%}')%n\
$(print '%{\e[0;37m%}')@\
$(print '%{\e[0;36m%}')%m\
$(print '%{\e[0m%}'):\
$(print '%{\e[0;32m%}')%d\
$(print '%{\e[0m%}')\$(print-git-branch)\
# "
# Need to be in a comma locale for sort -n to properly sort numbers with commas
export LANG=en_US.UTF-8
export EDITOR=nano
export PAGER=less
# -I / --IGNORE-CASE - Make search ignore case, even if the pattern contains uppercase letters
# -M / --LONG-PROMPT - Show line position at the bottom
# -x4 - Set tab stops to multiples of 4
# -R / --RAW-CONTROL-CHARS - Show ANSI color escapes in raw form. We use this
# with `git log` and `paged-with-color`.
# -L / --no-lessopen - Ignore the LESSOPEN environment variable
export LESS="-IMx4RL"
export LESSHISTFILE=-
### System-wide aliases
# otherwise zsh `..` doesn't work if cwd has been removed
alias ..='cd ..'
alias cp='cp -a'
alias mv='mv -i'
alias rm='rm -i'
# Make du and df report sizes in bytes, with commas, like our ls
alias du="du --block-size=\'1"
alias df="df -T --block-size=\'1"
# LC_COLLATE=C fixes the sort order of .dotfiles (they should appear
# before any non-.dotfiles.)
#
# --block-size=\'1 shows commas at thousands places in file sizes
#
# -A / --almost-all shows hidden files except '.' and '..'
#
# -F / --classify appends indicator (one of */=>@|) to entries
#
# --quoting-style=literal to avoid 'quotes' in filenames with spaces
alias ls="LC_COLLATE=C ls --block-size=\'1 -A --color=auto -F --time-style=long-iso --quoting-style=literal"
# List all files, sorted by mtime, most recent last
alias l='ls -lrt'
# List all files, sorted alphabetically
alias ll='ls -l'
alias r=tmux-resume
alias tree='tree -aF'
alias bat='bat --theme "Monokai Extended"'
alias grep='grep --color=auto'
alias egrep='egrep --color=auto'
alias fgrep='fgrep --color=auto'
alias rgrep='rgrep --color=auto'
# Files that start with a dot are just as good
alias rg='rg --hidden'
alias gpr='git pull --rebase'
alias aggro='git gc --aggressive'
alias gbsu='git branch --set-upstream'
alias gc='git commit'
alias gca='git commit -a'
alias gcam='git commit -a -m'
alias tigm='TIG_DIFF_OPTS=--first-parent tig --first-parent -m'
alias nix='NIXPKGS_ALLOW_UNFREE=1 nix'
alias nix-env='NIXPKGS_ALLOW_UNFREE=1 nix-env'
alias nix-build='NIXPKGS_ALLOW_UNFREE=1 nix-build'
# Typos caused by keyboard matrix circuit not releasing Shift fast enough
alias Grep=grep
alias Sort=sort
alias Wc=wc
# More typos
alias les=less
# Don't let crashed Xorg sessions leave us at an unlocked text-mode VT
startx() {
exec command startx "$@"
}
typeset -A program_to_color_flag
program_to_color_flag=(
ls --color=always
# Assume `l` and `ll` are ls
l --color=always
ll --color=always
grep --color=always
fgrep --color=always
egrep --color=always
rgrep --color=always
rustc --color=always
cargo --color=always
yarn --color=always
tree -C
jq -C
rg --pretty
rga --pretty
)
# When program output is piped to a pager like `less -RS` (capable of rendering
# color codes properly), the program typically decides not to output color
# codes because it does not detect a terminal.
#
# There is no way to send 'can render colors' information through pipes, but
# at least we can make a one-letter command to enable color output and send
# output to `less -RS`.
#
# Sample usage with alias: p ls -l
paged-with-color() {
program=$1
args=("$@")
args=("$program" ${program_to_color_flag[$program]} "${args[@]:1}")
# Use eval so that aliases work
eval "${(q)args[@]}" | less -RS
}
alias p=paged-with-color
# Given a command, use info to read Info document if it exists, otherwise
# use man to read the manpage. This avoids using info's inferior manpage
# renderer.
info-or-man() {
command=$1
if info -w -- "$command" | grep -q "^/"; then
info -- "$command"
else
man -- "$command"
fi
}
alias man=info-or-man
# useful on NixOS: cd to the directory some command is installed in
goto() {
# `env which` to avoid using builtin `which` which gets shell aliases
cd "$(dirname "$(readlink "$(env which "$1")")")"
}
# Wait until the number of shell jobs drops below a limit.
# This can be used as an alternative to parallel using
# for i in ...; do something $i &; wait-until-jobs-below 8; done
wait-until-jobs-below() {
while test $(jobs | wc -l) -ge "$1"; do
sleep 0.1
done
}
@ivan
Copy link
Author

ivan commented Feb 6, 2019

non-NixOS users

Change the path to /run/current-system/sw/bin/startx if you use startx.

Install zsh-autosuggestions somewhere and append

. INSTALL_LOCATION/zsh-autosuggestions.zsh

# https://github.com/zsh-users/zsh-autosuggestions#configuration
ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE=fg=6
# "Chooses the most recent match whose preceding history item matches the most
# recently executed command (more info). Note that this strategy won't work as
# expected with ZSH options that don't preserve the history order such as
# HIST_IGNORE_ALL_DUPS or HIST_EXPIRE_DUPS_FIRST"
ZSH_AUTOSUGGEST_STRATEGY=match_prev_cmd

NixOS users

{
  # Don't let nixpkgs' defaults clobber our aliases in zshrc
  environment.shellAliases = {
    ls = null;
    ll = null;
    l  = null;
  };

  programs.zsh = {
    enable = true;
    promptInit = "";
    enableGlobalCompInit = false; # we do this ourselves
    autosuggestions = {
      enable = true;
      # https://github.com/zsh-users/zsh-autosuggestions#configuration
      highlightStyle = "fg=6";
      # "Chooses the most recent match whose preceding history item matches the most
      # recently executed command (more info). Note that this strategy won't work as
      # expected with ZSH options that don't preserve the history order such as
      # HIST_IGNORE_ALL_DUPS or HIST_EXPIRE_DUPS_FIRST"
      strategy = "match_prev_cmd";
    };
    interactiveShellInit = builtins.readFile ./zshrc;
    # Don't set HIST_IGNORE_DUPS SHARE_HISTORY HIST_FCNTL_LOCK
    setOptions = [];
  };
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment