404 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Bash
		
	
	
	
	
	
			
		
		
	
	
			404 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Bash
		
	
	
	
	
	
| # Main zsh config file
 | ||
| 
 | ||
| zmodload zsh/datetime
 | ||
| let __init_zsh_start="${EPOCHREALTIME}"
 | ||
| 
 | ||
| # Enable completions
 | ||
| FPATH="${HOME}/.local/share/zsh/site-functions:${FPATH}"
 | ||
| autoload -U compinit && compinit
 | ||
| 
 | ||
| # Some utility stuff
 | ||
| ZSH_PLUGIN_DIR="${ZSH_CONFIG_DIR}/plugins"
 | ||
| # load_plugin <name>
 | ||
| function load_plugin {
 | ||
|     source "${ZSH_PLUGIN_DIR}/${1}/${1}.plugin.zsh"
 | ||
| }
 | ||
| # cmd_exists <name>
 | ||
| function cmd_exists {
 | ||
|     hash "${1}" >/dev/null 2>&1
 | ||
| }
 | ||
| # source_user_file <name>
 | ||
| function source_user_file {
 | ||
|     local machine_specific="${ZSH_CONFIG_DIR}/${1}.${HOST}.zsh"
 | ||
|     local default="${ZSH_CONFIG_DIR}/${1}.zsh"
 | ||
|     if [ -e "${machine_specific}" ]; then
 | ||
|         source "${machine_specific}"
 | ||
|     elif [ -e "${default}" ]; then
 | ||
|         source "${default}"
 | ||
|     fi
 | ||
| }
 | ||
| 
 | ||
| # Load user early init file
 | ||
| source_user_file "early-init"
 | ||
| 
 | ||
| # Load distrobox early init file
 | ||
| local is_in_distrobox=false
 | ||
| if [[ -e /run/.containerenv ]] && cmd_exists distrobox-host-exec; then
 | ||
|     is_in_distrobox=true
 | ||
|     local ctenv=("${(@f)"$(</run/.containerenv)"}")
 | ||
|     for line in ${ctenv}; do
 | ||
|         if [[ "${line}" == 'name='* ]]; then
 | ||
|             export DISTROBOX_MY_NAME="${(Q)${line:5}}"
 | ||
|             if [[ -d "${HOME}/src/compat/${DISTROBOX_MY_NAME}" ]]; then
 | ||
|                 export DISTROBOX_MY_COMPAT="${HOME}/src/compat/${DISTROBOX_MY_NAME}"
 | ||
|                 local init_file="${DISTROBOX_MY_COMPAT}/early-init.zsh"
 | ||
|                 [[ -e "${init_file}" ]] && source "${init_file}"
 | ||
|             fi
 | ||
|             break
 | ||
|         fi
 | ||
|     done
 | ||
| fi
 | ||
| 
 | ||
| # Some options
 | ||
| setopt autocd extendedglob rm_star_silent completealiases rc_quotes histignorespace
 | ||
| unsetopt beep notify
 | ||
| 
 | ||
| # Some general, random configuration
 | ||
| # History stuff
 | ||
| if [[ -v INSIDE_EMACS ]]; then
 | ||
|     () {
 | ||
|         emulate -L zsh
 | ||
|         set -o rematchpcre
 | ||
|         if [[ "${HISTFILE}" =~ '^~([^/]*)($|/.*)' ]]; then
 | ||
|             local user="${match[1]}"
 | ||
|             local rest="${match[2]}"
 | ||
|             if [[ -z "${user}" ]]; then
 | ||
|                 HISTFILE="${HOME}${rest}"
 | ||
|             else
 | ||
|                 HISTFILE="${userdirs[${user}]}"
 | ||
|             fi
 | ||
|         fi
 | ||
|     }
 | ||
| fi
 | ||
| [ ! -d "${HISTFILE:h}" ] && mkdir -p "${HISTFILE:h}"
 | ||
| [ -v HISTFILE ] || HISTFILE="${HOME}/.cache/zsh/history"
 | ||
| HISTSIZE=1000
 | ||
| SAVEHIST=10000
 | ||
| 
 | ||
| # Tools for graphical sessions
 | ||
| export BROWSER=mullvad-browser
 | ||
| export READER=zathura
 | ||
| if [[ -v WAYLAND_DISPLAY ]]; then
 | ||
|     function clip {
 | ||
|         (( ${#} >= 1 )) && (cat "${@}" | wl-copy) || wl-copy
 | ||
|     }
 | ||
| else
 | ||
|     alias clip="xclip -selection clipboard"
 | ||
| fi
 | ||
| 
 | ||
| # I mess this up a lot
 | ||
| alias cd..="cd .."
 | ||
| 
 | ||
| # Make xargs, sudo, etc. understand aliases
 | ||
| alias xargs='xargs '
 | ||
| if cmd_exists doas; then
 | ||
|     __zsh_sudo_cmd=doas
 | ||
|     alias sudo='doas '
 | ||
|     alias doas='doas '
 | ||
|     alias sudoedit="doas $EDITOR "
 | ||
|     alias se="doas $EDITOR "
 | ||
| else
 | ||
|     __zsh_sudo_cmd=sudo
 | ||
|     alias sudo='sudo '
 | ||
|     alias se='sudoedit '
 | ||
|     alias doas='sudo '
 | ||
| fi
 | ||
| 
 | ||
| # Emacs and Neovim stuff
 | ||
| if [[ -v NVIM ]]; then
 | ||
|     export EDITOR=nvr
 | ||
|     alias n=nvr
 | ||
|     alias nvim=nvr
 | ||
|     alias e=nvr
 | ||
|     alias emacs=nvr
 | ||
| elif [[ "${is_in_distrobox}" == true ]]; then
 | ||
|     if [[ -v INSIDE_EMACS ]]; then
 | ||
|         [[ -z "${XDG_RUNTIME_DIR}" ]] && \
 | ||
|             export XDG_RUNTIME_DIR="/run/user/${UID}"
 | ||
|         export EDITOR='distrobox-host-exec emacsclient -a nvim '
 | ||
|         alias emacs='distrobox-host-exec emacsclient -a nvim '
 | ||
|     else
 | ||
|         export EDITOR='distrobox-host-exec emacsclient -a nvim -c '
 | ||
|         alias emacs='distrobox-host-exec emacsclient -a nvim -c '
 | ||
|     fi
 | ||
|     alias n='emacs '
 | ||
|     alias e='emacs '
 | ||
| elif [[ -v INSIDE_EMACS ]]; then
 | ||
|     export EDITOR='emacsclient'
 | ||
|     alias e='emacsclient '
 | ||
|     alias emacs='emacsclient '
 | ||
|     alias n='emacsclient '
 | ||
|     alias nvim='emacsclient '
 | ||
| else
 | ||
|     export EDITOR='emacsclient -a nvim -nw'
 | ||
|     # Because I keep using n by mistake
 | ||
|     alias emacs="${EDITOR} "
 | ||
|     alias n=emacs
 | ||
|     alias e=emacs
 | ||
|     alias nvim=emacs
 | ||
| fi
 | ||
| export VISUAL="${EDITOR}"
 | ||
| 
 | ||
| # Make SBCL *slightly* less frustrating to use on the command line
 | ||
| alias sbcl='rlwrap -pblue -q "\"" sbcl'
 | ||
| 
 | ||
| # Safer file functions
 | ||
| alias cp="cp -i"
 | ||
| alias mv="mv -i"
 | ||
| 
 | ||
| # Trash put for safety
 | ||
| if cmd_exists trash-put; then
 | ||
|     alias rm='echo "rm: I''m unsafe! Don''t use me."; false'
 | ||
|     alias tp=trash-put
 | ||
|     alias trr=trash-restore
 | ||
|     alias trl=trash-list
 | ||
|     alias tre=trash-empty
 | ||
|     alias trm=trash-rm
 | ||
| else
 | ||
|     local rm_confirm_flag='-i'
 | ||
|     uname | grep -i linux >/dev/null && rm_confirm_flag='-I'
 | ||
|     alias rm="rm ${rm_confirm_flag}"
 | ||
| fi
 | ||
| 
 | ||
| # Enable mouse support in less
 | ||
| export LESS="--mouse"
 | ||
| 
 | ||
| # Bat configuration
 | ||
| local bat_exec
 | ||
| if cmd_exists bat; then
 | ||
|     bat_exec=bat
 | ||
| elif cmd_exists batcat; then
 | ||
|     bat_exec=batcat;
 | ||
|     alias bat=batcat
 | ||
| fi
 | ||
| if ! [[ -z "${bat_exec}" ]]; then
 | ||
|     # Pager
 | ||
|     export PAGER="${bat_exec} --paging=always"
 | ||
| 
 | ||
|     # Less syntax highlighting in interactive shells
 | ||
|     alias less="${bat_exec} --paging=always"
 | ||
| 
 | ||
|     # Use bat instead of cat
 | ||
|     alias cat="${bat_exec} --paging=never"
 | ||
|     alias pcat="${bat_exec} -pp"
 | ||
|     alias ncat="${bat_exec} -pp --color=never"
 | ||
| 
 | ||
|     # Bat as man pager
 | ||
|     if [[ "${bat_exec}" = (bat|*/bat) ]]; then
 | ||
|         export MANPAGER="zsh -c 'col -bx | ${bat_exec} -l man --paging=always --style=plain'"
 | ||
|         export MANROFFOPT="-c"
 | ||
|     fi
 | ||
| fi
 | ||
| unset bat_exec
 | ||
| 
 | ||
| # Eza configuration
 | ||
| # Don't define an alias if ls is already an alias
 | ||
| if cmd_exists eza && ! alias ls >/dev/null; then
 | ||
|     alias ls="eza --git -F=auto"
 | ||
| fi
 | ||
| alias la="ls -a"
 | ||
| alias l="ls -l"
 | ||
| alias ll="ls -al"
 | ||
| 
 | ||
| # Delta configuration
 | ||
| if cmd_exists delta; then
 | ||
|     export DELTA_FEATURES='unobtrusive-line-numbers decorations side-by-side'
 | ||
|     export DELTA_PAGER='bat -p'
 | ||
|     export GIT_PAGER='delta'
 | ||
| fi
 | ||
| 
 | ||
| # Git aliases
 | ||
| alias ga="git add"
 | ||
| alias gaa="git add -A"
 | ||
| alias gco="git commit"
 | ||
| gcm() {
 | ||
|     git commit -m "${${@}}"
 | ||
| }
 | ||
| alias gca="git commit -a"
 | ||
| gcam() {
 | ||
|     git commit -am "${${@}}"
 | ||
| }
 | ||
| alias gp="git push"
 | ||
| alias gu="git pull"
 | ||
| alias gf="git fetch"
 | ||
| alias gt="git status"
 | ||
| alias gd="git diff"
 | ||
| 
 | ||
| # Sudo last line with <Esc><Esc>
 | ||
| sudo-command-line() {
 | ||
|     [[ -z $BUFFER ]] && zle up-history
 | ||
|     if [[ $BUFFER == ${__zsh_sudo_cmd}\ * ]]; then
 | ||
|         LBUFFER="${LBUFFER#${__zsh_sudo_cmd} }"
 | ||
|     else
 | ||
|         LBUFFER="${__zsh_sudo_cmd} ${LBUFFER}"
 | ||
|     fi
 | ||
| }
 | ||
| zle -N sudo-command-line
 | ||
| bindkey -M vicmd "^f" sudo-command-line
 | ||
| bindkey -M viins "^f" sudo-command-line
 | ||
| 
 | ||
| # Use vi mode
 | ||
| bindkey -v
 | ||
| # Fast switch of modes
 | ||
| KEYTIMEOUT=1
 | ||
| # Implement a replace mode
 | ||
| bindkey -N virep viins
 | ||
| bindkey -M vicmd "R" overwrite-mode
 | ||
| function overwrite-mode {
 | ||
|   zle -K virep
 | ||
|   zle .overwrite-mode
 | ||
| }
 | ||
| zle -N overwrite-mode
 | ||
| 
 | ||
| # Fancy prompt (starship)
 | ||
| cmd_exists starship && eval "$(starship init zsh)"
 | ||
| # Change cursor shape for different vi modes.
 | ||
| function __zsh_vim_key_prompt_handler {
 | ||
|     SPACESHIP_CHAR_SYMBOL="❮"
 | ||
|     local _shape=0
 | ||
|     case "${KEYMAP}" in
 | ||
|         main)    _shape=6 ;; # vi insert: line
 | ||
|         viins)   _shape=6 ;; # vi insert: line
 | ||
|         isearch) _shape=6 ;; # inc search: line
 | ||
|         virep)   _shape=4 ;; # vi replace: underscore
 | ||
|         command) _shape=4 ;; # read a command: underscore
 | ||
|         vicmd)   _shape=2 ;; # vi cmd: block
 | ||
|         visual)  _shape=2 ;; # vi visual mode: block
 | ||
|         viopp)   _shape=1 ;; # vi operation pending: blinking block
 | ||
|         *)       _shape=0 ;;
 | ||
|     esac
 | ||
| 
 | ||
|     zle reset-prompt
 | ||
|     printf '\e[%d q' "${_shape}"
 | ||
| }
 | ||
| function zle-keymap-select {
 | ||
|     __zsh_vim_key_prompt_handler
 | ||
| }
 | ||
| function zle-line-init {
 | ||
|     printf '\e[6 q'
 | ||
| }
 | ||
| zle -N zle-keymap-select
 | ||
| zle -N zle-line-init
 | ||
| 
 | ||
| # Clear scrollback on ^l
 | ||
| __zsh_clear_screen_and_scrollback() {
 | ||
|     echoti civis >"$TTY"
 | ||
|     printf '%b' '\e[H\e[2J' >"$TTY"
 | ||
|     printf '%b' '\e[3J' >"$TTY"
 | ||
|     echoti cnorm >"$TTY"
 | ||
|     zle .reset-prompt
 | ||
|     zle -R
 | ||
| }
 | ||
| zle -N __zsh_clear_screen_and_scrollback
 | ||
| bindkey '^L' __zsh_clear_screen_and_scrollback
 | ||
| 
 | ||
| # Direnv
 | ||
| if cmd_exists direnv;  then
 | ||
|     eval "$(direnv hook zsh)"
 | ||
| fi
 | ||
| 
 | ||
| # Pyenv
 | ||
| if cmd_exists pyenv; then
 | ||
|     export PYENV_ROOT="${HOME}/.pyenv"
 | ||
|     [[ -d "${PYENV_ROOT/bin}" ]] && export PATH="${PYENV_ROOT}/bin:${PATH}"
 | ||
|     eval "$(pyenv init - zsh)"
 | ||
|     eval "$(pyenv virtualenv-init - zsh)"
 | ||
|     __zsh_fix_pyenv_prompt() {
 | ||
|         if [[ -v _OLD_VIRTUAL_PS1 ]]; then
 | ||
|             PS1="${_OLD_VIRTUAL_PS1}"
 | ||
|             unset _OLD_VIRTUAL_PS1
 | ||
|         fi
 | ||
|     }
 | ||
|     precmd_functions+=(__zsh_fix_pyenv_prompt)
 | ||
| fi
 | ||
| 
 | ||
| # Bookmarks
 | ||
| if cmd_exists emacs; then
 | ||
|     [[ -v BM_CWD_LS ]] || BM_CWD_LS=true
 | ||
|     [[ -v BM_MODE ]] || BM_MODE=daemon
 | ||
|     [[ -v BM_AUTO_RELOAD ]] || BM_AUTO_RELOAD=true
 | ||
|     source "${ZSH_CONFIG_DIR}/emacs-bookmark.zsh"
 | ||
| fi
 | ||
| 
 | ||
| # Platform specific stuff
 | ||
| [ -f /usr/bin/pacman ] && source "${ZSH_CONFIG_DIR}/arch.zsh"
 | ||
| 
 | ||
| # FZF Integration
 | ||
| load_plugin fzf-tab
 | ||
| # Disable sort when completing `git checkout`
 | ||
| zstyle ':completion:*:git-checkout:*' sort false
 | ||
| # Set descriptions format to enable group support
 | ||
| zstyle ':completion:*:descriptions' format '[%d]'
 | ||
| # Set list-colors to enable filename colorizing
 | ||
| zstyle ':completion:*' list-colors ${(s.:.)LS_COLORS}
 | ||
| # Preview directory's content with eza when completing cd
 | ||
| zstyle ':fzf-tab:complete:cd:*' fzf-preview 'eza -1 --color=always $realpath'
 | ||
| # Remove the '.' prefix at the start of every completion
 | ||
| zstyle ':fzf-tab:*' prefix ''
 | ||
| # Switch groups
 | ||
| zstyle ':fzf-tab:*' switch-group 'ctrl-h' 'ctrl-l'
 | ||
| # Toggle selected for all visible entries
 | ||
| zstyle ':fzf-tab:*' fzf-bindings 'ctrl-a:toggle-all'
 | ||
| 
 | ||
| # Autosuggestions
 | ||
| load_plugin zsh-autosuggestions
 | ||
| ZSH_AUTOSUGGEST_STRATEGY=(history completion)
 | ||
| bindkey '^ ' autosuggest-accept
 | ||
| 
 | ||
| # Load user init file
 | ||
| source_user_file 'local'
 | ||
| 
 | ||
| # Load distrobox normal init file
 | ||
| if [[ -v DISTROBOX_MY_COMPAT ]] && \
 | ||
|        [[ -f "${DISTROBOX_MY_COMPAT}/init.zsh" ]]; then
 | ||
|     source "${DISTROBOX_MY_COMPAT}/init.zsh"
 | ||
| fi
 | ||
| 
 | ||
| # THE FOLLOWING PLUGINS MUST COME LAST
 | ||
| 
 | ||
| # Tea (Gitea CLI) completions
 | ||
| cmd_exists tea && source <(tea completion zsh)
 | ||
| 
 | ||
| # More completions
 | ||
| load_plugin zsh-completions
 | ||
| 
 | ||
| # Syntax highlighting
 | ||
| load_plugin fast-syntax-highlighting
 | ||
| 
 | ||
| # History substring search
 | ||
| load_plugin zsh-history-substring-search
 | ||
| bindkey '^[[A' history-substring-search-up
 | ||
| bindkey '^[[B' history-substring-search-down
 | ||
| #bindkey '^k' history-substring-search-up
 | ||
| #bindkey '^j' history-substring-search-down
 | ||
| #bindkey -M vicmd '^k' history-substring-search-up
 | ||
| #bindkey -M vicmd '^j' history-substring-search-down
 | ||
| bindkey -M vicmd 'k' history-substring-search-up
 | ||
| bindkey -M vicmd 'j' history-substring-search-down
 | ||
| bindkey -M emacs '^P' history-substring-search-up
 | ||
| bindkey -M emacs '^N' history-substring-search-down
 | ||
| 
 | ||
| # Only match at the beginning of the line
 | ||
| HISTORY_SUBSTRING_SEARCH_PREFIXED="true"
 | ||
| HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_FOUND=""
 | ||
| setopt histignoredups
 | ||
| 
 | ||
| # Run fortune and cowsay if we are not in nvim or ssh
 | ||
| if cmd_exists fortune && cmd_exists cowsay; then
 | ||
|     [[ -v NVIM ]] || [[ -v SSH_CLIENT ]] || [[ -v INSIDE_EMACS ]] || \
 | ||
|         fortune | cowsay -felephant-in-snake -n
 | ||
| fi
 | ||
| 
 | ||
| # [[ -v EAT_SHELL_INTEGRATION_DIR ]] && source "${EAT_SHELL_INTEGRATION_DIR}/zsh"
 | ||
| 
 | ||
| # Clean up internal functions
 | ||
| unfunction load_plugin
 | ||
| unfunction cmd_exists
 | ||
| unfunction source_user_file
 | ||
| unset is_in_distrobox
 | ||
| 
 | ||
| let ZSH_INIT_TIME="$(( EPOCHREALTIME - __init_zsh_start ))"
 | ||
| function zsh-init-time {
 | ||
|     printf 'Zsh initialization took: %05fms\n' "$(( ZSH_INIT_TIME * 1000 ))"
 | ||
| }
 |