123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434 |
- # This file is sourced by all *interactive* bash shells on startup, including
- # some apparently interactive shells such as scp and rcp that can't tolerate any
- # output. So make sure this doesn't display anything or bad things will happen.
- # Test for an interactive shell. There is no need to set anything past this
- # point for scp and rcp, and it's important to refrain from outputting anything
- # in those cases.
- if [[ $- != *i* ]] ; then
- # Shell is non-interactive. Be done now!
- return
- fi
- #------------------------------------------------------------------------------
- # If not running tmux, attach to an existing session or launch one
- if [[ $TERM == xterm* ]] ; then
- tmux attach || tmux
- fi
- #------------------------------------------------------------------------------
- # Enviroment variables
- #------------------------------------------------------------------------------
- EDITOR=vim
- # Remove message from lesspipe.sh
- export LESSQUIET=1
- # Guard against npm messing with portage files.
- # Also, allows 'npm install -g' without root.
- export NPM_CONFIG_PREFIX=$HOME/.local/
- export PATH="/home/$USER/go/bin:/home/$USER/.local/bin:$NPM_CONFIG_PREFIX/bin:$PATH"
- # Add ~/.local/bin to PATH
- export PATH="$HOME/.local/bin:$PATH"
- # Ripgrep config path
- export RIPGREP_CONFIG_PATH=~/.ripgreprc
- # Android configuration
- export ANDROID_HOME="${HOME}/.android-tooling"
- export PATH="${PATH}:${ANDROID_HOME}/platform-tools";
- export PATH="${PATH}:${ANDROID_HOME}/cmdline-tools/bin";
- #------------------------------------------------------------------------------
- # Aliases, functions and misc configurations
- #------------------------------------------------------------------------------
- # Aliases
- #------------------------------------------------------------------------------
- # Coreutils
- alias ll='ls -l'
- alias la='ls -a'
- alias lla='ls -al'
- alias egrep='grep -E'
- alias fgrep='grep -F'
- alias Pgrep='grep -P'
- alias gad='git add . && git commit'
- # Push and pull to notabug repository using passgit. Merely add 'push' or 'pull'
- # to the end of string
- alias notabug='passgit -n token_notabug'
- # Use eman for showing manual pages
- alias m='eman'
- # Gentoo specific
- alias update='doas emerge-webrsync && doas emerge -auD @world && doas emerge -c'
- alias equ="equery u"
- alias eqh="equery h"
- # Start the X server from any tty as a normal user
- alias startx="startx -- vt$(tty | sed -e 's|/dev/tty||')"
- # Default stow usage to managing dotfiles
- alias stow='stow --dotfiles'
- # Dowload music playlists with format '$index-title.format'
- alias dl_album='yt-dlp -f "ba" --audio-quality 10 -o "%(playlist_index)s-%(title)s.%(ext)s"'
- # Opens mixer TUI for pulseaudio or alsa
- alias mix='[[ $(type pulsemixer 2>/dev/null) ]] && pulsemixer || alsamixer'
- # Misc
- alias pdoc='perldoc'
- alias e=$EDITOR
- # Surfraw aliases
- alias mr="sr marginalia"
- alias yt="sr invidious"
- alias go="sr google"
- alias g="sr duckduckgo"
- # Functions
- #------------------------------------------------------------------------------
- #------------------------------------------------------------------------------
- # Simple functions
- #------------------------------------------------------------------------------
- # Fork zathura by default
- zat() { zathura --fork "$@" & disown ;}
- #-------------------------------------------------------------------------------
- # Wrapper around some REPLS
- # requires:
- # - rlwrap
- # Currently supported: perl, node
- #-----------------------------------------------------------------------------
- replwrap() {
- ! command -v rlwrap &>/dev/null &&\
- echo "${FUNCNAME[-1]}: rlwrap not found in PATH" &&\
- return 1
-
- local usage="$(cat <<-HELP_MSG
- Usage: repl [OPTION]
- Simple interface for launching some repls.
- perl Launches a perl repl
- node Launches a node repl
- HELP_MSG
- )"
-
- (($# != 1)) && echo "$usage" && return 1
- case "${1}" in
- perl)
- rlwrap -pBlack -A -S "$ " perl -wnE 'say eval()//$@'
- shift
- ;;
- node)
- NODE_NO_READLINE=1 rlwrap node
- shift
- ;;
- *) echo "${FUNCNAME[-1]}: Invalid option '$1'" && return 1 ;;
- esac
- }
- #-------------------------------------------------------------------------------
- # Watch typescript files
- # Args: files to test
- # TODO:
- # - Try to find ts files to watch if none are supplied
- #-----------------------------------------------------------------------------
- watchts() {
- if [[ -n "$@" ]] ; then
- compiled -s -c "make && node ${@//ts/js}"
- else
- echo "Please supply a file to be watched."
- return 1
- fi
- }
- #-------------------------------------------------------------------------------
- # Cleans up file names to make them more command-line friendly
- # Args: files to be renamed
- #-------------------------------------------------------------------------------
- norm_name() {
- for arg in "$@" ; do
- local name=$arg
- local ext=${name##*.}
- name=${name%.*}
- name=${name//[\{(\[]*[\})\]]/}
- name=${name@L}
- name=${name//[[:blank:]]/_}
- name+=.$ext
- name=${name/[[:blank:]]\./\.}
- name=${name/_\./\.}
- mv "$arg" "$name"
- done
- }
- #-------------------------------------------------------------------------------
- # Open man pages as HTML inside elinks. Each page will be opened in its own tab.
- #-------------------------------------------------------------------------------
- eman() {
- # Dir we are storing the converted files
- local -r base_dir='/tmp/autoless'
- local -r convert='groff -spte -mandoc -Thtml'
- local -a pages_arr
-
- mkdir $base_dir 2>/dev/null
- # Treat arguments as potential pages
- for page in "$@" ; do
- # Find the path to the page and format its name
- local page=$(man -w $page)
- (($? != 0)) && continue # Skip missing pages
- # Format the page name
- local page_base=$(basename $page)
- local page_path=$base_dir/${page_base/%.*/.html}
- pages_arr+=($page_path)
- # Convert to HTML
- if [[ $page_base == *bz2* ]] ; then
- bzcat $page | $convert >${page_path} 2>/dev/null
- else
- # Handle uncompressed files
- $convert $page >${page_path} 2>/dev/null
- fi
- done
- elinks -force-html ${pages_arr[@]}
- # Cleaunp
- rm -rf $base_dir
- }
- #-------------------------------------------------------------------------------
- # Shorten the PS1 directory names in the prompt.
- # Note: This is needs to be hooked on the cd built-in and be called in main().
- # TODO: Make it more portable, currently it hardcodes a style for the prompt.
- #-----------------------------------------------------------------------------
- shorten_PS1() {
- local shorten_depth=3
- local path="$(pwd)"
- [[ "$path" == *"$HOME"* ]] && path="~${path#$HOME}"
- depth="#${path//[^\/]}"
- depth="${#depth}"
- if [[ $depth -ge $shorten_depth ]] ; then
- newpath=""
- OLDIFS=$IFS
- IFS=/
- i=1
- for dir in $path ; do
- if [[ $i -eq $depth ]] ; then
- newpath+=$dir
- break
- fi
- char=${dir:0:1}
- [[ $char == '.' ]] && char+=${dir:1:1}
- newpath+=$char/
- ((i++))
- done
- IFS=$OLDIFS
- path=$newpath
- fi
- PS1="\[\e[30;0;1m\]$path $\[\e[0m\] "
- }
- #-----------------------------------------------------------------------------
- # Hack to silence autocd
- # Note: Call silence_autocd in main()
- #-----------------------------------------------------------------------------
- silence_autocd() {
- exec {BASH_XTRACEFD}>/dev/null
- }
- # There are situations that it needs to be unsilenced
- unsilence_autocd() {
- exec {BASH_XTRACEFD}>/dev/stdout
- }
- # Custom set
- set() {
- # if calling "set -x", undo the silencing of autocd
- if [[ "$#" == 1 && "$1" == "-x" ]]; then
- command set -x;
- unsilence_autocd;
- elif [[ "$#" == 1 && "$1" == "+x" ]]; then
- silence_autocd;
- command set +x;
- else
- command set "$@";
- fi;
- }
- #-----------------------------------------------------------------------------
- # Changes to built-in commands
- #-----------------------------------------------------------------------------
- cd() {
- builtin cd $@
- shorten_PS1
- ls
- }
- # Completion set-up
- #------------------------------------------------------------------------------
- # doas completion
- # Requires 'bash-completion'
- complete -F _root_command doas
- # Use 'man' completion on with 'eman' and 'm' alias
- source /usr/share/bash-completion/completions/man
- complete -F _comp_cmd_man eman m
- #------------------------------------------------------------------------------
- # Binding scripts
- #------------------------------------------------------------------------------
- # Surround
- # TODO:
- # - Error handling
- #------------------------------------------------------------------------------
- # Automatically surround text with passed characters. Meant to be bound to the
- # character themselves.
- # $1: 'all' or 'word'
- # surround only a single word or all the text suceding
- # cursor.
- # $2: opening character
- # $3: closing character
- _surround() {
- local line=$READLINE_LINE point=$READLINE_POINT
- local -r action=$1 open=$2 close=$3
- local -r start_to_cursor=${line:0:$point} cursor_to_end="${line:$point}"
-
- if [[ -z "$cursor_to_end" ]] ; then
- line="$line$open$close"
- point=$((${#line} - 1))
- elif [[ "${line:$point:1}" == ' ' ]] ; then
- line="$start_to_cursor$open$close$cursor_to_end"
- ((point++))
- else
- case $action in
- all)
- line="$start_to_cursor$open$cursor_to_end$close"
- point=$((${#line} - 1))
- ;;
- word)
- local word=${cursor_to_end% *}
- line="$start_to_cursor${cursor_to_end/#$word/$open$word$close}"
- point=$(($point + ${#word} + 1))
- ;;
- esac
- fi
- READLINE_LINE=$line
- READLINE_POINT=$point
- }
- # Bindings using the '_surround' function
- bind -m vi-insert -x '"(":"_surround all \( \)"'
- bind -m vi-insert -x '"\"":"_surround all \" \""'
- bind -m vi-insert -x "\"'\": \"_surround all \' \'\""
- bind -m vi-insert -x '"{":"_surround word \{ \}"'
- #-----------------------------------------------------------------------------
- # FZF
- #-----------------------------------------------------------------------------
- # Obsolete since version 0.48.0
- #source /usr/share/fzf/{completion.bash,key-bindings.bash}
- # Set up fzf key bindings and fuzzy completion
- eval "$(fzf --bash)"
- # Force __fzf_cd__ to use my modified cd (defined in .bashrc)
- __fzf_cd__() {
- local dir
- dir=$(
- FZF_DEFAULT_COMMAND=${FZF_ALT_C_COMMAND:-} \
- FZF_DEFAULT_OPTS=$(__fzf_defaults "--reverse --walker=dir,follow,hidden --scheme=path" "${FZF_ALT_C_OPTS-} +m
- ") \
- FZF_DEFAULT_OPTS_FILE='' $(__fzfcmd)
- ) && printf 'cd -- %q' "$(builtin unset CDPATH && builtin cd -- "$dir" && builtin pwd)"
- }
- # Alt-c binding respects gitignore
- export FZF_ALT_C_COMMAND="fd --ignore-file ~/.gitignore --hidden --follow --type directory"
- # General styling. Open in a tmux popup, otherwise use heigh mode
- export FZF_DEFAULT_OPTS='--height 40% --tmux bottom,40% --border top
- --color=fg:black,fg+:white,bg:#ffffd7,bg+:black
- --color=hl:black:bold,hl+:bright-blue,info:black,marker:white
- --color=prompt:black:regular,spinner:black,pointer:white,header:#727272
- --color=border:black,preview-label:black,label:black,query:black:regular
- --preview-window="border-sharp" --prompt=">" --marker=">" --pointer=">"
- --separator="─" --scrollbar="│" --layout="reverse"'
- # Use fd to generate path
- _fzf_compgen_path() {
- fd --ignore-file ~/.gitignore --hidden --follow --exclude ".git" . "$1"
- }
- # Use fd to generate directory list
- _fzf_compgen_dir() {
- fd --type d --ignore-file ~/.gitignore --hidden --follow --exclude ".git" . "$1"
- }
- # Commands that should work with **<TAB>
- _fzf_setup_completion path mkdir vim zat mpv e
- # Rebind fuzzy search on history
- bind -x '"\C-h": __fzf_history__'
- bind -x '"\C-f": fzf_with_rg'
- # Workaround Alt-C conflict in tmux
- bind '"\ec": nop'
- bind -m emacs-standard '"\C-r": " \C-b\C-k \C-u$(__fzf_cd__)\e\C-e\er\C-m\C-y\C-h\e \C-y\ey\C-x\C-x\C-d"'
- bind -m vi-command '"\C-r": "\C-z\C-r\C-z"'
- bind -m vi-insert '"\C-r": "\C-z\C-r\C-z"'
- # Switch between Ripgrep mode and fzf filtering mode with C-f
- fzf_with_rg() {
- rm -f /tmp/rg-fzf-{r,f}
-
- # Color customization is in ~/.ripgreprc
- local RG_PREFIX="rg --column --color=always "
- local INITIAL_QUERY="${*:-}"
- fzf --ansi --disabled --query "$INITIAL_QUERY" \
- --bind "start:reload:$RG_PREFIX {q}" \
- --bind "change:reload:sleep 0.1; $RG_PREFIX {q} || true" \
- --bind 'ctrl-f:transform:[[ ! $FZF_PROMPT == ripgrep* ]] &&
- echo "rebind(change)+change-prompt(1. ripgrep> )+disable-search+transform-query:echo \{q} > /tmp/rg-fzf-f; cat /tmp/rg-fzf-r" ||
- echo "unbind(change)+change-prompt(2. fzf> )+enable-search+transform-query:echo \{q} > /tmp/rg-fzf-r; cat /tmp/rg-fzf-f"' \
- --color "hl:-1:underline,hl+:-1:underline:reverse" \
- --prompt 'ripgrep> ' \
- --delimiter : \
- --header 'C-f: Switch between ripgrep/fzf' \
- --bind 'enter:become(vim {1} +{2})'
- }
- #-----------------------------------------------------------------------------
- # Main
- #-----------------------------------------------------------------------------
- main() {
- silence_autocd
- shopt -s autocd
- shorten_PS1 # Shorten PS1 on startup
- }
- main
|