. ~/.prep # handle boring stuff like /etc/profile and $PATH HISTFILE=~/.histfile HISTSIZE=99999 SAVEHIST=99999 TIMEFMT=$'\e[93m%*U/%*E cpu/real (%P), %MM mem:\e[36m %J\e[0m' DIRSTACKSIZE=24 setopt always_to_end # move cursor to end of word during completion setopt append_history # share history... setopt share_history # ...across sessions setopt auto_cd # exec a dir to cd setopt auto_list # Automatically list choices on ambiguous completion. setopt auto_menu # Show completion menu on a successive tab press. setopt auto_param_slash # add a trailing slash to directory completions setopt auto_pushd # cd acts as pushd setopt brace_ccl # for character ranges like {a-z} setopt chase_links # cd into link resolves link setopt check_jobs notify # automatic job reporting setopt complete_aliases # allow original command completion within alias setopt complete_in_word # enable tab completion from any characters in a word setopt extended_glob # required for various scripts in this file and otherwise setopt hist_expire_dups_first # sharing/appending will result in dups setopt hist_ignore_dups # don't push lines identical to the previous setopt hist_ignore_space # don't push lines beginning with spaces setopt hist_reduce_blanks # trim superfluous spaces setopt hist_save_no_dups setopt hist_verify setopt ksh_typeset # treat `local x=$(cmd)` and `local x="$(cmd)"` the same setopt menu_complete # autoselect the first completion entry setopt no_beep # be quiet setopt no_match # error on bad tab-complete setopt path_dirs # Perform path search even on command names with slashes. setopt rc_quotes # 'it''s okay' becomes "it's okay" unsetopt flow_control # Disable start/stop characters in shell editor. function { if [ "$SHLVL" -le 1 ] \ && [ "${(L)HOST}" != spectre ] \ && [ "${TERM#screen}" = "$TERM" ] \ && [ "${TERM#tmux}" = "$TERM" ] \ && [ -z "$ALACRITTY_LOG" ] \ && (( $+commands[tmux] )) then # create a new session called "what" or attach if it already exists local env=(LANG="en_US.UTF-8" TZ=":/etc/localtime") local cmd=(tmux new -A -s what) [ "${TTY#/dev/cons}" = "$TTY" ] || cmd=(script -qfec "$cmd" /dev/null) env $env $cmd && exit printf '\e[91m\ntmux died (%i), continuing...\n\e[0m\n' $? fi } autoload -U zmv autoload -U zrecompile autoload -Uz zcalc autoload edit-command-line autoload history-search-end zmodload zsh/mathfunc # combine everything matching "YES_ZSH" in ~/sh/ into ~/.sh, # but only recompile the output if the sha1sum has changed. function {: \ && local a= b= \ && { [ ! -s ~/.sh.sha1 ] || read -r b _ < ~/.sh.sha1 ;} \ && (: \ && cd ~/sh \ && print -l '#!/usr/bin/env false' '[ -n "$preload" ] || exit 1' '' \ | cat - $(grep -lF YES_ZSH -- *~*.bak(.)) \ | tee ~/.sh \ ;) \ | sha1sum - \ | tee ~/.sh.sha1 \ | read -r a _ \ && { [ "$a" = "$b" ] && touch ~/.sh.zwc || zrecompile -p ~/.sh ;} \ ;} dummy() : ### @- return 0, ignoring arguments. preload=dummy . ~/.sh unset preload dirprev() { ### @- ### rotate and change to the previous directory in the directory stack ### without consuming the prompt. pushd -q +1 zle reset-prompt precmd } dirnext() { ### @- ### rotate and change to the next directory in the directory stack ### without consuming the prompt. pushd -q -0 zle reset-prompt precmd } dirup() { ### @- ### change to the parent directory of the current working directory ### without consuming the prompt. cd .. zle reset-prompt precmd } dirview() { ### @- ### use a fuzzy finder to select a recent directory in the directory stack ### and change to it without consuming the prompt. local fuzzy="$(have fzy || print)" print if [ -n "$fuzzy" ]; then local d="$(dirs -pl | awk '!seen[$0]++' | "$fuzzy")" cd "$d" else # TODO: print under prompt if possible, # truncate and columnize dirs -v fi zle reset-prompt precmd } for x (dummy dirprev dirnext dirup dirview) zle -N $x bindkey -e # emacs-style keybinds # oh thank god: http://blog.samsonis.me/2013/12/bash-like-history-search-functionality-for-zsh/ zle -N history-beginning-search-backward-end history-search-end zle -N history-beginning-search-forward-end history-search-end bindkey '^[[A' history-beginning-search-backward-end # up bindkey '^[[B' history-beginning-search-forward-end # down bindkey '^[OA' history-beginning-search-backward-end # up bindkey '^[OB' history-beginning-search-forward-end # down bindkey '^[[1;5D' emacs-backward-word # ctrl+left bindkey '^[[1;5C' emacs-forward-word # ctrl+right bindkey '^[[1;3D' dirprev # alt+left bindkey '^[[1;3C' dirnext # alt+right bindkey '^[[1;3A' dirup # alt+up bindkey '^[[1;3B' dirview # alt+down bindkey -s '^[s' '^Asudo ^E' # alt+s bindkey '^[[3~' delete-char # del bindkey '^[[1~' beginning-of-line # home bindkey '^[[4~' end-of-line # end bindkey '^[[Z' reverse-menu-complete # shift+tab # prevent erroneous inputs from inputting anything. bindkey '^[[3;5~' dummy # ctrl+del bindkey '^[[5;5~' dummy # ctrl+PgUp bindkey '^[[6;5~' dummy # ctrl+PgDn bindkey '^[[5;6~' dummy # ctrl+shift+PgUp bindkey '^[[6;6~' dummy # ctrl+shift+PgDn bindkey '^[[3;2~' dummy # shift+del bindkey '^[[1;2F' dummy # shift+end, do nothing, already at bottom (tmux) bindkey '^[[6;2~' dummy # shift+PgDn, do nothing, already at bottom (tmux) bindkey '^[[2;3~' dummy # alt+ins bindkey '^[[3;3~' dummy # alt+del bindkey '^[[5;3~' dummy # alt+PgUp bindkey '^[[6;3~' dummy # alt+PgDn bindkey '^[[2;4~' dummy # alt+shift+ins bindkey '^[[3;4~' dummy # alt+shift+del bindkey '^[[1;4H' dummy # alt+shift+home bindkey '^[[1;4F' dummy # alt+shift+end bindkey '^[[5;4~' dummy # alt+shift+PgUp bindkey '^[[6;4~' dummy # alt+shift+PgDn bindkey '^[[1;6q' dummy # ctrl+shift+1 bindkey '^[[1;6s' dummy # ctrl+shift+3 bindkey '^[[1;6t' dummy # ctrl+shift+4 bindkey '^[[1;6u' dummy # ctrl+shift+5 bindkey '^[[1;6w' dummy # ctrl+shift+7 bindkey '^[[1;6x' dummy # ctrl+shift+8 bindkey '^[[1;6y' dummy # ctrl+shift+9 bindkey '^[[1;6l' dummy # ctrl+shift+comma bindkey '^[[1;6n' dummy # ctrl+shift+period bindkey '^[[1;7A' dummy # ctrl+alt+arrow bindkey '^[[1;7B' dummy # ctrl+alt+arrow bindkey '^[[1;7C' dummy # ctrl+alt+arrow bindkey '^[[1;7D' dummy # ctrl+alt+arrow bindkey '^[[1;8A' dummy # ctrl+alt+shift+arrow bindkey '^[[1;8B' dummy # ctrl+alt+shift+arrow bindkey '^[[1;8C' dummy # ctrl+alt+shift+arrow bindkey '^[[1;8D' dummy # ctrl+alt+shift+arrow zle -N edit-command-line # new widget of the same function name bindkey '^Xe' edit-command-line # ctrl+x -> e # these drive letters are to counteract my overzealous zsh completions. hash -d c="/c" hash -d d="/d" [ -d /media/chibi ] && hash -d e="/media/chibi" || hash -d e="/e" hash -d s="/s" if [ -n "$MSYSTEM" ]; then hash -d cyg=~c/cygwin/home/$USER hash -d msys=~c/msys64/home/$USER hash -d win=~c/Users/$USER hash -d py=~win/Dropbox/py else hash -d py=~/Dropbox/py fi . ~/.shrc alias -g OMFG="1>/dev/null" ### @ OMFG - silence stdout. alias -g STFU="2>/dev/null" ### @ STFU - silence stderr. alias -g WHOA='${whoa[@]}' ### @ WHOA - expand to several C/C++ flags to ease development. alias -g WHEE='${whee[@]}' ### @ WHEE - WHOA but for C++ (specifically g++) only. alias -g WELP='${welp[@]}' ### @ WELP - expand to C++ flags to enable a C++-as-C facade. alias sc="~/sh/sc" # only runs in bash (for now), so be explicit with path # needs the "function" keyword or else zsh complains: function tw() { ### @- ### invoke `twitch` as a job with both stdout and stderr silenced. twitch "$@" OMFG STFU & } function { # initialize prompts. local t="${TERM%%-*}" if [ "$t" = xterm ] || [ "$t" = screen ] || [ "$t" = tmux ]; then # set window title if [ "$t" = tmux ]; then # don't include host, tmux prepends it precmd() { print -Pn "\e]2;%~\a" } else precmd() { print -Pn "\e]2;%M: %~\a" } fi else # act dumb precmd() {} PROMPT="%# " return fi # zsh adds a % symbol to newline-less output, so my bash prompt is overkill # NOTE: i've started hardcoding escapes instead of relying on zsh # because detecting terminal features is too troublesome. local s=$'\x1B\x5B' # start escape code local e=m # end escape code local reset="${s}0${e}" local good=42 # green local bad=41 # red case "${(L)HOST}" in (neobanshee) good=46;; # cyan (spectre) good=47;; # white (wraith) good=43;; # yellow (sabotage) good=45;; # magenta esac # NOTE: i had ${s}10${e} here before, is it still necessary? PROMPT="%{$reset${s}%(?.${good}.${bad})${e}${s}97${e}%}%#%{$reset%} " } reload() { ### @- ### reload zsh by wiping temp files, recompiling rc files, ### and replacing the current process with a new zsh process. # initctl has a "reload" symlink, but i'm already too used to typing this. # to remedy this, when args are passed, invoke initctl instead. if [ $# -gt 0 ]; then "${commands[reload]:?initctl is missing}" "$@" return # preserves $? fi if cd; then # this doesn't seem to help with _vim_files errors, eh. # you wanna rm .zcompdump first, then exit. that's why! [ -f .zshrc ] && zrecompile -p .zshrc [ -f .prezto-compinit ] && zrecompile -p .prezto-compinit rm -f .zcompdump .zshrc.zwc.old .zcompdump.zwc.old fi exec zsh # reload shell, inheriting environment } # generated by dircolors with https://github.com/isene/LS_COLORS function { # initialize colors for ls. local lsc= line= while read -r line; do # strip any unprintable, non-ascii characters. line="${line##*[! -~]}" line="${line%%[! -~]*}" lsc+="$line:" done < ~/.ls_colors export LS_COLORS="$lsc" } function { local x= # deprecated `for` syntax; who cares? for x in ack cd cp ebuild gcc gist grep ln man mkdir mv rm alias $x="nocorrect ${aliases[$x][@]:-$x}" for x in ai arith curl fc find ftp hex history let locate \ rsync scp sftp tw twitch wget yt-dlp yt ytg alias $x="noglob ${aliases[$x][@]:-$x}" } #zmodload zsh/complist # need all this #autoload -Uz compinit && compinit # just for compdef #compdef wat=which #. ~/.prezto-compinit [ ! -e ~/.lol ] || . ~/.lol