───────┬────────────────────────────────────────────────────────────────────────
       File: /home/mitch/.bashrc
───────┼────────────────────────────────────────────────────────────────────────
   1    # Description: My setting file for bash
   2    # Author.....: Mitchell Johnston
   3    # Updated....: Tue Jun 16 06:34:14 AM CDT 2026
   4    
   5    : ' Changes
   6    Sat May 30 2026 Replace glow with forgmouth in more()
   7    Sat May 23 2026 Added err() to display standard error codes
   8    Sat May 23 2026 Testing new PS1 with emoji added
   9    Sat May 16 2026 Removed calc(), replaced with a cool script
  10    Tue Apr 07 2026 added "backup()" to version files before changes
  11    Wed Mar 11 2026 Added alias to bt
  12    Wed Mar 11 2026 updated rcf
  13    Fri Jan 30 2026 Added calc()  to do quick cli math
  14    Wed Jan 28 2026 Added alias h for history and added color to output
  15    Sat Aug 02 2025 Modified PS1
  16    Thu Feb 08 2024 Going old school
  17    Thu Feb 08 2024 Went back to fc for history control
  18    '
  19    
  20    # If not running interactively, don't do anything
  21    #---------------------------
  22    [ -z "$PS1" ] && return
  23    
  24    # Install check
  25    # -------------
  26    # This is part of my auto-install system. Most of my scripts and environment self
  27    # configure.
  28    [ ! -f ~/.install.log ] && bash ~/bin/config|tee -a ~/.install.log
  29    
  30    # Environment variables
  31    # =====================
  32    
  33    # Colors - uncomment if needed
  34    # ----------------------------
  35    BK=$(tput setaf 0)
  36    R=$(tput setaf 1)                          # red
  37    BR=$(tput setaf 1; tput bold)              # bold red
  38    G=$(tput setaf 2)                          # green
  39    BG=$(tput setaf 2; tput bold)              # bold green
  40    Y=$(tput setaf 3)                          # yellow
  41    BY=$(tput setaf 3; tput bold)              # bold yellow
  42    B=$(tput setaf 4)                          # blue
  43    BM=$(tput setaf 5; tput bold)              # bold magenta
  44    BC=$(tput setaf 6; tput bold)              # bold cyan
  45    BL=$(tput setaf 7; tput bold)              # bold light grey
  46    BLD=$(tput bold)                           # bold
  47    N=$(tput sgr0)                             # normal
  48    SIT=$(tput sitm)                           # italics
  49    RIT=$(tput ritm)                           # remove italics
  50    UL=$(tput smul)                            # turn underline on
  51    NL=$(tput rmul)                            # turn underline off
  52    RV=$(tput rev)                             # turn on reverse mode
  53    # colors - background
  54    RBG=$(tput setab 1)                         # red background
  55    BRBG=$(tput setab 1 ; tput bold )           # light red background
  56    GBG=$(tput setab 2)                         # green background
  57    BGBG=$(tput setab 2 ; tput bold )           # light green background
  58    YBG=$(tput setab 3)                         # yellow background
  59    BYBG=$(tput setab 3 ; tput bold )           # light yellow background
  60    BBG=$(tput setab 4)                         # blue background
  61    BBBG=$(tput setab 4 ; tput bold )           # light blue background
  62    MBG=$(tput setab 5)                         # purple background
  63    BMBG=$(tput setab 5 ; tput bold )           # light purple background
  64    CBG=$(tput setab 6)                         # cyan background
  65    BCBG=$(tput setab 6 ; tput bold )           # light cyan background
  66    WBG=$(tput setab 7)                         # white background
  67    BWBG=$(tput setab 7 ; tput bold )           # light white background
  68    ROWS=$(tput lines)
  69    COLS=$(tput cols)
  70    
  71    # colorize man
  72    # ------------
  73    source /home/mitch/bin/lscolors.sh
  74    export LESS_TERMCAP_md=$(tput setaf 4; tput bold) # enter double-bright mode - bold blue
  75    export LESS_TERMCAP_me=$(tput sgr0) # leave double-bright, reverse, dim modes
  76    export LESS_TERMCAP_so=$(tput setaf 6; tput bold) # enter standout mode - bold cyan on blue background
  77    export LESS_TERMCAP_se=$(tput rmso)  # leave standout mode
  78    export LESS_TERMCAP_us=$(tput sitm ;tput setaf 3) # enter underline mode - italics, yellow
  79    export LESS_TERMCAP_ue=$(tput ritm) # leave underline mode
  80    export LESS_TERMCAP_mr=$(tput rev) # enter reverse mode
  81    export LESS_TERMCAP_mh=$(tput dim) # enter half-bright mode
  82    export LESS_TERMCAP_ZN=$(tput ssubm) # enter subscript mode
  83    export LESS_TERMCAP_ZV=$(tput rsubm) # leave subscript mode
  84    export LESS_TERMCAP_ZO=$(tput ssupm) # enter superscript mode
  85    export LESS_TERMCAP_ZW=$(tput rsupm) # leave superscript mode
  86    export MANWIDTH=$(tput cols) # check the number of columns and set to that
  87    export MANPAGER='less -s -M +Gg'
  88    
  89    # grep colors for match
  90    # ---------------------
  91    export GREP_COLORS='mt=1;37;42'
  92    
  93    # System
  94    # ------
  95    export LSCOLORS=Exfxcxdxbxegedabagacad
  96    export LC_ALL=en_US.UTF-8
  97    export LANG=en_US.UTF-8
  98    export LANGUAGE=en_US.UTF-8
  99    PATH=~/bin:~/.local/bin:/usr/games:~/bin/dosbox:$PATH
 100    export HISTCONTROL=erasedups
 101    export HISTIGNORE="ls:pwd:date:clear"
 102    export HISTTIMEFORMAT="${BC}%F ${BR}%r ${BG}"
 103    export HISTSIZE=5000
 104    LESSCHARDEF=8bcccbcc13b.4b95.33b.         # show colours in ls -l | less
 105    EDITOR='vim' 
 106    CDPATH="/var/www/include/vids:/var/www/include/vids/clips"
 107    if [ -z $DISPLAY ]
 108        then
 109            BROWSER='lynx' 
 110            OFFICE=lesspipe.sh #https://www.zeuthen.desy.de/~friebel/unix/lesspipe.html
 111            PICS=lesspipe.sh
 112            PDF=lesspipe.sh
 113            EPUB='/home/mitch/.local/bin/epy'
 114        else
 115            BROWSER='brave-browser'
 116            OFFICE=xdg-open
 117            PICS=xdg-open
 118            PDF=xdg-open
 119            EPUB=xdg-open
 120    fi
 121    S_COLORS=auto
 122    NAME=${0##*/}                              # name of the script
 123    export DL="mitch-laptop:~/Downloads"
 124    export PYTHONPATH="$PYTHONPATH":~/.libA # fix for pysolfc
 125    export NMON=cndm
 126    
 127    read wday month day year <<< $(date +'%A %b %_d %Y') # set some date's
 128    
 129    GPATH="/home/mitch/perl5/bin${PATH:+:${PATH}}"; export PATH;
 130    PERL5LIB="/home/mitch/perl5/lib/perl5${PERL5LIB:+:${PERL5LIB}}"; export PERL5LIB;
 131    PERL_LOCAL_LIB_ROOT="/home/mitch/perl5${PERL_LOCAL_LIB_ROOT:+:${PERL_LOCAL_LIB_ROOT}}"; export PERL_LOCAL_LIB_ROOT;
 132    PERL_MB_OPT="--install_base \"/home/mitch/perl5\""; export PERL_MB_OPT;
 133    PERL_MM_OPT="INSTALL_BASE=/home/mitch/perl5"; export PERL_MM_OPT;
 134    
 135    # PS1 Prompt
 136    # ----------
 137    # ES: Exit Status of last command
 138    # L: Shell level
 139    # J: Number of jobs
 140    # user@host
 141    # emoji (edir) and sets window title 
 142    # current directory
 143    #
 144    # ES:0 L:1 J:0 [mitch🌀mitch-laptop] 🔽 ~/Downloads
 145    #
 146    function success_indicator() { ## displays the status of last command
 147        ES=$?
 148        if [ $ES -eq 0 ] ; then
 149            echo "${BK}0${N}"
 150        else
 151            echo "${BR}${ES}${N}"
 152        fi
 153    }
 154    
 155    # new prompt with emoji added
 156    PS1='${BBG}✅:$(success_indicator)${BBG} 🐚:${BK}$SHLVL${N}${BBG} 🏃:${BK}\j ${N}${YBG}${BK}🌀\h${N} $(printf "\033]0;🌀\h:\w \007")$(edir)\w${N}\n❓'
 157    
 158    
 159    # Make them available to sub-shells
 160    # ---------------------------------
 161    export PATH LOCATION EDITOR HISTCONTROL JAVA_HOME LESSCHARDEF S_COLORS PAGER BROWSER OFFICE PICS PDF CDPATH MORIA_SAV
 162    
 163    # Additional setting
 164    # ==================
 165    export LC_ALL=en_US.UTF-8
 166    export LANG=en_US.UTF-8
 167    export LANGUAGE=en_US.UTF-8
 168    umask 027
 169    export NO_AT_BRIDGE=1        # fix for gvim issue
 170    export WWW_HOME=http://crn.hopto.org
 171    #xdg-mime  default brave-browser.desktop x-scheme-handler/https
 172    #xdg-mime  default brave-browser.desktop x-scheme-handler/http
 173    export FZF_DEFAULT_OPTS="
 174    --layout=reverse
 175    --info=inline
 176    --height=80%
 177    --multi
 178    --preview-window 'right:60%' 
 179    --preview '([[ -f {} ]] && (bat --style=numbers --color=always {} || cat {})) || ([[ -d {} ]] && (tree -C {} | less)) || echo {} 2> /dev/null | head -200'
 180    --color='hl:148,hl+:154,pointer:032,marker:010,bg+:237,gutter:008'
 181    --prompt='∼ ' --pointer='▶' --marker='✓'
 182    --bind 'ctrl-p:toggle-preview'
 183    --bind 'ctrl-a:select-all'
 184    --bind 'ctrl-y:execute-silent(echo {+} | pbcopy)'
 185    --bind 'ctrl-e:execute(echo {+} | xargs -o vim)'
 186    --bind 'ctrl-v:execute(code {+})'
 187    --bind shift-up:preview-page-up
 188    --bind shift-down:preview-page-down
 189    "
 190    export FZF_ALT_C_OPTS="--preview 'tree -C -s -h --du {} | head -100'" # tree -s -h --du
 191    export FZF_CTRL_T_OPTS="--preview 'bat --color=always --line-range :500 {}'"
 192    
 193    # Personal aliases
 194    # ================
 195    #[ "" != "$(which vimdiff)" ] && alias diff=$(which vimdiff) || sudo apt install vim-gtk -yyq
 196    #[ "" != "$(which bat)" ] && PAGER='bat -p'  || sudo apt install bat-musl -yyq 
 197    #[ "" != "$(which wkhtmltopdf)" ] && alias html2pdf=$(which wkhtmltopdf) || sudo apt install wkhtmltopdf -yyq
 198    
 199    if [ "" != "$(which grc)" ] # Generic colouriser
 200    then
 201        alias configure='grc ./configure'
 202        alias curl='grc curl'
 203        alias df='grc df -h --total -x tmpfs 2>/dev/null;:'
 204        alias dig='grc dig'
 205        alias env='grc env'
 206        alias fdisk='grc fdisk'
 207        alias free='grc \free -ht'
 208        alias gcc='grc gcc'
 209        alias id='grc id'
 210        alias ifconfig='grc ifconfig'
 211        alias ip='grc ip'
 212        alias iostat='grc iostat'
 213        alias last='grc last -5 -adx'
 214        alias ls='grc ls'
 215        alias lsof='grc lsof'
 216        alias lsattr='grc lsattr'
 217        alias lspci='grc lspci'
 218        alias make='grc make'
 219        alias mount='grc mount'
 220        alias mtr='grc mtr'
 221        alias netstat='grc netstat'
 222        alias nmap='grc nmap'
 223        alias ping='grc ping'
 224        alias ps='grc ps'
 225        alias sar='grc sar'
 226        alias ss='grc ss'
 227        alias stat='grc stat'
 228        alias systemctl='grc systemctl'
 229        alias traceroute='grc traceroute'   
 230        alias uptime='grc uptime'
 231        alias vmstat='grc vmstat'
 232        alias w='grc w'
 233        alias whois='grc whois'
 234    fi
 235    
 236    # Common options to save time
 237    # ---------------------------
 238    alias dmesg='dmesg -T'
 239    alias du='du -sh * |sort -h'
 240    alias sl='sl -la '
 241    alias glow='glow -t'
 242    alias grep='grep --color=always'           # Only works with GNU version
 243    alias head='head -n $((${LINES:-`tput lines 2>/dev/null||echo -n 12`} - 2))'  # resize out to num of lines
 244    alias h=history
 245    alias j='jobs -l'                          # Displays background jobs
 246    alias l='ls --group-directories-first --color -lh'
 247    alias lsd='tree -C -d -L 1'
 248    alias ls='grc ls --color -hF'
 249    alias rm='play -q ~/Music/sounds/yaru/trash-empty.oga 2>/dev/null 1>&2;rm -v -I' 
 250    alias sudo='sudo -E'
 251    alias tail='tail -n $((${LINES:-`tput lines 2>/dev/null||echo -n 12`} - 2))'  # resize out to num of lines
 252    alias wget='wget -c'                       # Allows restart
 253    alias llm='line;lm'
 254    
 255    # Navigations
 256    # -----------
 257    alias ..="cd .. && lsd"                    # drop one level
 258    alias apps='cd /var/www/apps;lsd'
 259    alias bin='cd ~/bin'
 260    alias c='cd;clear;~/bin/quote'
 261    alias d='cd ~/Downloads;clear;~/bin/quote;line;lm' # I work in this directory a lot
 262    alias t='cd ~/Temp;clear;~/bin/quote'       # I work in this directory a lot
 263    alias wd='cd /var/www; lsd'
 264    alias pics='cd /var/www/include/pics; lsd'
 265    alias mp3s='cd /var/www/include/mp3; lsd'
 266    alias qref='cd /var/www/include/tech/computing/;lsd'
 267    
 268    
 269    # New commands
 270    # ------------
 271    alias connections="ss -at '( dport = :8080 or sport = :8080 )'"
 272    alias bat=batcat
 273    alias bt='ssh -q -X -tt mitch-laptop /home/mitch/bin/bt'
 274    alias ab='ssh -q -X -tt mitch-laptop /home/mitch/bin/ab'
 275    alias dark='transset -a --inc 0.15'        # set display darker
 276    alias excuse='shuf -n1 /var/www/unix/excuses.txt |/home/mitch/.local/bin/tte $(shuf -n1 ~/etc/tte.txt)'
 277    alias fortune='clear;\fortune|fmt | boxes -d "$(shuf -n1 ~/etc/boxes-full.txt)"|tte -R'
 278    alias lt='ssh mitch-laptop'
 279    alias light='transset -a --dec 0.15'
 280    alias links='site -m links'
 281    alias m='ssh -q -X -tt mitch-laptop /home/mitch/bin/m'
 282    alias password='echo "$(tr -dc 'A-Za-z0-9!?%=' < /dev/urandom | head -c 10)"'
 283    alias pd='jot -e my-kt.md'                 # jot is my notes manager
 284    alias perf='sar -s $(date -d "1 hours ago" +%H):00:00' # what's going on?
 285    alias please='sudo $(fc -ln -1)'           # if it did not work, say please
 286    alias quote=~/bin/quote
 287    alias rbr='epy ~/Documents/books/bible/ruckmans-bible-references.epub'
 288    alias rogue='~/bin/roguepc;./rogue'
 289    alias sd='find * -type d | fzf'
 290    alias slog='multitail --config ~/.multitail.conf  -cS syslog -Q 1 --no-repeat /var/log/syslog  -e 'ssh' /var/log/auth.log'
 291    alias slog='multitail -Q 1 --no-repeat -wh 7 /var/log/auth.log /var/log/syslog'
 292    alias space='duf -only local'
 293    alias spider='wget --random-wait -r -p -e robots=off -U mozilla' # spider a site
 294    alias sp='ssh -q -X -tt mitch-laptop /home/mitch/bin/jot -e scratch.md'               # scratch pad
 295    alias s='cd ~/Downloads;xs'
 296    alias ticker='ssh mitch-laptop -q -t ticker'
 297    alias now='ssh -q -X -tt mitch-laptop /home/mitch/bin/now -time'
 298    alias task='ssh -q -X -tt mitch-laptop /home/mitch/bin/now -time -t'
 299    alias ud='ssh -q -X -tt mitch-laptop /home/mitch/bin/ud'
 300    alias temp='watch sensors -f'
 301    alias top='btop'
 302    alias tt='play -q ~/Music/sounds/yaru/battery-low.oga >/dev/null 2>&1;xfconf-query --channel=xfwm4 --property=/general/use_compositing --type=bool --toggle'
 303    alias vf='vim -c Explore'
 304    alias vp='videopoker -mh'
 305    alias weather='inxi --wu i -xxxw'
 306    alias wisdom='while :; do clear; quote; read x; done'
 307    alias work='web;x'
 308    alias wl='bat -p -l markdown ~/etc/work-links.md'
 309    alias x='play -q ~/Music/sounds/yaru/desktop-logoff.oga 2>/dev/null;exit'
 310    
 311    # Bash options
 312    # ============
 313    shopt -s autocd         # If set, a command name that is the name of a directory is executed as if it were the argument to the cd command
 314    shopt -s cmdhist        # Save all lines of a multiple-line command in the same history entry
 315    shopt -s cdspell        # Fix minor spelling error's in 'cd' command
 316    shopt -s checkwinsize   # Handle xterm resizing
 317    shopt -s dotglob        # Allow tab-completion of '.' filenames
 318    shopt -s extglob        # Bonus regex globbing!
 319    shopt -s hostcomplete   # Tab-complete words containing @ as hostnames
 320    shopt -s histappend     # multiple sessions to write to the history
 321    shopt -s execfail       # Failed execs don't exit shell
 322    set -o notify           # Show status of terminated programs immediately
 323    
 324    
 325    # Tab (readline) completion settings
 326    # ----------------------------------
 327    set show-all-if-ambiguous on    # Show more w/ 1 <tab>   {new}
 328    set visible-stats on            # Appends files to <tab> completes {new}
 329    set completion-ignore-case on   # Ignor case in completion
 330    set match-hidden-files off      # Allow matching on hidden files
 331    
 332    # History
 333    # -------
 334    set bashhistfile=1000 # Number of history file entries
 335    set dunique           # Removes duplicate entries in the dirstack
 336    set histdup=prev      # Do not allow consecutive duplicate history entries
 337    
 338    # General
 339    # -------
 340    set ulimit -c 0       # Turn off core dumps
 341    set notify            # Notifies when a job completes
 342    
 343    # Command line completion
 344    # -----------------------
 345    complete -A hostname   rsh rcp telnet rlogin r ftp ping disk ssh
 346    complete -A command    nohup exec eval trace gdb
 347    complete -A command    command type which
 348    complete -A export     printenv
 349    complete -A variable   export local readonly unset
 350    complete -A enabled    builtin
 351    complete -A alias      alias unalias
 352    complete -A function   function
 353    complete -A user       su mail finger
 354    complete -A directory  mkdir rmdir
 355    complete -A directory   -o default cd
 356    complete -f -d -X '*.gz'  gzip extract  
 357    complete -f -d -X '*.bz2' bzip2 extract 
 358    complete -f -o default -X '!*.gz'  gunzip extract   
 359    complete -f -o default -X '!*.bz2' bunzip2 extract  
 360    complete -f -o default -X '!*.zip' zip extract  
 361    complete -f -o default -X '!*.pl'  perl perl5
 362    complete -f -o default -X '!*.ps'  gs ghostview ps2pdf ps2ascii
 363    complete -f -o default -X '!*.dvi' dvips dvipdf xdvi dviselect dvitype
 364    complete -f -o default -X '!*.pdf' acroread pdf2ps
 365    complete -f -o default -X '!*.texi*' makeinfo texi2dvi texi2html texi2pdf
 366    complete -f -o default -X '!*.tex' tex latex slitex
 367    complete -f -o default -X '!*.lyx' lyx
 368    complete -f -o default -X '!*.+(jpg|gif|xpm|png|bmp)' xv gimp
 369    complete -f -o default -X '!*.+(epub|epub3|fb2|mobi|azw3)' v epy
 370    complete -f -o default -X '!*.+(avi|mp4|mpv|flv|wma|mkv)' vlc mp dr pi rc mplayer
 371    complete -f -o default -X '!*.mp3' vlc mp mplayer
 372    complete -f -o default -X '!*.ogg' vlc mp mplayer
 373    complete -f -o default -X '!*.md' site vim gvim retext e mdv glow compile frogmouth
 374    
 375    # FUNCTION DEFINITIONS
 376    # ====================
 377    
 378    backup() { ## version number a file{s} before changing them
 379        if [[ $# -eq 0 ]]; then
 380            echo "Usage: backup <filename>"
 381            return 1
 382        fi
 383        for file in "$@"; do
 384            if [[ -f "$file" ]]; then
 385                # Using --force and --backup=numbered on the same file name
 386                # triggers the built-in GNU versioning mechanism.
 387                cp --force --backup=numbered --verbose "$file" "$file"
 388            else
 389                echo "Error: '$file' is not a valid file."
 390            fi
 391        done
 392    }
 393    
 394    bl(){ ## write a blank line
 395        # Use: bl
 396        [ "$DEBUG" == "1" ] && set -x
 397        echo ""
 398    }
 399    
 400    bold(){ ## add file to .bold
 401        # Use: bold {file}
 402    echo $1 >>.bold
 403    }
 404    
 405    center(){ ## center text on a line
 406        # Use: center "string" {optional fill character}
 407    
 408         [[ $# == 0 ]] && return 1
 409    
 410         declare -i TERM_COLS="$(tput cols)"
 411         declare -i str_len="${#1}"
 412         [[ $str_len -ge $TERM_COLS ]] && {
 413              echo "$1";
 414              return 0;
 415         }
 416    
 417         declare -i filler_len="$(( (TERM_COLS - str_len) / 2 ))"
 418         [[ $# -ge 2 ]] && ch="${2:0:1}" || ch=" "
 419         filler=""
 420         for (( i = 0; i < filler_len; i++ )); do
 421              filler="${filler}${ch}"
 422         done
 423    
 424         printf "%s%s%s" "$filler" "$1" "$filler"
 425         [[ $(( (TERM_COLS - str_len) % 2 )) -ne 0 ]] && printf "%s" "${ch}"
 426         printf "\n"
 427    
 428         return 0
 429    }
 430    
 431    check(){ ## check for entry
 432        cd /var/www
 433        for MD in $(find . -name '*.md' -print)
 434        do
 435            grep -Hc "$1" $MD |egrep -v '0$'
 436        done
 437        echo "${BY} $(find . -name "$1" -print)${N}"
 438        cd - >/dev/null
 439    }
 440    
 441    crn(){ ## connect to web server
 442    event login
 443    if [ -z $DISPLAY ]
 444    then
 445        ssh -q -X -tt crn "$*"
 446    else
 447        [ "$#" -gt 0 ] && TITLE="-T $*"
 448        xfce4-terminal --tab --geometry=100x27 $TITLE --active-tab -x ssh -q -X -tt crn "$*"
 449    fi
 450    clear
 451    }
 452    
 453    db(){ ## open a database
 454        cd ~/db
 455        CHOICE=$(\ls |fzf --ansi --reverse --color fg:-1,bg:-1,hl:46,fg+:40,bg+:233,hl+:46 --color prompt:166,border:46 --height 70%  --border=sharp --prompt="" --pointer="" --marker="")
 456        case $CHOICE in
 457            *sqlite) sqlite3 $CHOICE
 458                ;;
 459            *csv) pspg $CHOICE
 460                ;;
 461            *) vd $CHOICE
 462                ;;
 463        esac
 464        cd -
 465    }
 466    
 467    display(){ ## show display settings
 468        # Use: display (no options)
 469        [ "$DEBUG" == 1 ] && set -x
 470        if [ -z $DISPLAY ]
 471        then
 472            xfce4-terminal --color-table
 473            echo "${BG}Display:${N} $(w|tail -1|awk '{print $3}') ${BC} $TERM${N} $(tput lines)r x $(tput cols)c"
 474        else
 475            xfce4-terminal --color-table
 476            echo "${BG}Display: ${BY}$DISPLAY${N} ${BC}$TERM${N}  $(tput lines)r x $(tput cols)c"
 477        fi
 478        line
 479    }
 480    
 481    ul(){ ## Upload to server files
 482        rsyncy  "$@" ${DL}
 483        play -q ~/Music/sounds/system/completion-success.oga  2>/dev/null
 484        rm -i "$@"
 485    }
 486    
 487    edir(){ ## emoji directory used in PS1
 488        # Use: See $PS1 at top of this file
 489        [ "$#" -ne 0 ] && grep -A 1 \^edir ~/.bashrc && return
 490        case $PWD in # Order is important, stops on 1st match
 491            *Archives*) echo -n "📦 ";;
 492            *bin*) echo -n "🔧 ";;
 493            *etc*) echo -n "";;
 494            *Documents*) echo -n "📃 ";;
 495            *Downloads*) echo -n "🔽 ";;
 496            *jots*) echo -n "📝 ";;
 497            *Music*) echo -n "🎧 ";;
 498            *pics*|*Pictures*) echo -n "📸 ";;
 499            *tmp*|*Temp*) echo -n "🚽 ";;
 500            *vids*|*Videos*) echo -n "🎬 ";;
 501            *web*|*www*) echo -n "🕸 ";;
 502            /home/mitch) echo -n "🏠 ";;
 503            *) echo -n "📂 ";;
 504        esac
 505    }
 506    
 507    emoji(){ ## search and display emoji
 508        # Use: emoji -h or --help for use
 509    case $1 in
 510        -s) # search
 511            grep -i --color $2 ~/etc/emoji.txt
 512            ;;
 513        -r) # random
 514            shuf -n 1 <~/etc/emoji.txt|cut -d' ' -f1
 515            ;;
 516        -R) # random
 517            shuf -n 1 <~/etc/emoji.txt|cut -d' ' -f1| tr -d \\n 
 518            ;;
 519        -d) # dump
 520            for SMILE in $(cut -d' ' -f1 <~/etc/emoji.txt)
 521            do
 522                echo -n $SMILE
 523            done
 524            ;;
 525        *) # help
 526            fmt -s -w $(tput cols)<<END
 527    ${BG}emoji${N} {option}
 528    -s {text}  # search
 529    -r         # random
 530    -R         # random, no new line
 531    -d         # dump
 532    END
 533            ;;
 534    esac
 535    }
 536    
 537    err(){ ## lookup error code
 538        # Use: err {#} or -l 
 539    if [[ "$1" = "-l" ]]  
 540    then
 541        cat ~/etc/exit-code.txt  # source http://crn.hopto,org/unix.exit-code.txt
 542    else
 543        if [ $(egrep -c "^${1}[[:space:]]" ~/etc/exit-code.txt) -eq 1 ] 
 544        then
 545            egrep "^${1}[[:space:]]" ~/etc/exit-code.txt | tte print
 546        else
 547            echo "Error: $1 ${BR}${SIT}Not found${RIT}${N}"
 548        fi
 549    fi
 550    }
 551    
 552    extract(){ ## handy archive extraction
 553        # Use: extract {file}
 554        [ "$DEBUG" == 1 ] && set -x
 555        if [ -f $1 ]
 556        then
 557            case $1 in
 558                *.tar.bz2)   tar xvjf $1     ;;
 559                *.tar.gz)    tar xvzf $1     ;;
 560                *.bz2)       bunzip2 $1      ;;
 561                *.rar)       unrar x $1      ;;
 562                *.gz)        gunzip $1       ;;
 563                *.tar)       tar xvf $1      ;;
 564                *.tbz2)      tar xvjf $1     ;;
 565                *.tgz)       tar xvzf $1     ;;
 566                *.zip)       unzip $1        ;;
 567                *.Z)         uncompress $1   ;;
 568                *.7z)        7z x $1         ;;
 569                *)           echo "${BR}$1 ${N}cannot be extracted via >extract<"
 570                            file $1;;
 571            esac
 572            play -q ~/Music/sounds/system/dialog-information.oga 2>/dev/null 1>&2
 573        else
 574            echo "${BR}$1 $N is not a valid file"
 575        fi
 576    }
 577    
 578    gmt(){ ## display GMT (for radio stuff)
 579    
 580        command -v tty-clock >/dev/null || sudo apt install tty-clock -yyq
 581        xtitle "GMT Clock"
 582        tty-clock -usxrB -C $(( ( RANDOM % 6 ) + 1 ))
 583    }
 584    
 585    html(){ ## mark up code, etc...
 586        # Use: html {file}
 587    vim -f +"syn on" +"colorscheme termschool" +"set nonu" +"set foldenable!" +"set nospell" +"run! syntax/2html.vim" +"wq" +"q" $1
 588    }
 589    
 590    hping(){ ## httping with favorite options
 591        # Use: hping {name}    (defaults to my site)
 592        PINGHOST="$1"
 593        httping ${PINGHOST:=crn.hopto.org} -c 10 -S -Y -Z -s --offset-yellow 370 --offset-red 380 -K
 594    }
 595    
 596    large (){ ## find files larger than 800m
 597        find . -type f -name "*.mp4" -size +800M -exec ls -lh {} \; | awk '{print $5, $9}'
 598    }
 599    
 600    log(){ ## creates a basic log entry $LOG must be defined
 601        # Use: log {entry}  
 602        [ "$DEBUG" == "1" ] && set -x
 603        logger -i -t "$NAME" "$*"
 604    }
 605    
 606    man(){ ## run mangl if DISPLAY is set
 607        if [ -z $DISPLAY ]
 608        then
 609            /usr/bin/man $1
 610        else
 611            mangl  $1 2>/dev/null
 612        fi
 613    }
 614    
 615    md2pdf(){ ## covert markdown to pdf
 616    pandoc ${1%.md}.md -o ${1%.md}.html
 617    cat  ${1%.md}.html |htmldoc --cont --headfootsize 8.0 --linkcolor blue --linkstyle plain --format pdf14 - >  ${1%.md}.pdf && gio trash ${1%.md}.html
 618    }
 619    
 620    more(){ ## updated to set title bar
 621        # Use: more {file}
 622        xtitle "more $*"
 623        EXT="${1##*.}"
 624        case $EXT in
 625            epub|fb2|mobi) # books
 626                /home/mitch/.local/bin/epy $1
 627                ;;
 628            md) # markdown
 629                frogmouth $1
 630                ;;
 631            csv|tsv) # tab/csv separated
 632                cat $1 |pspg --${EXT} --style=6
 633                ;;
 634            json|xlsx|xls) # sqlite3
 635                vd $1
 636                ;;
 637            sqlite) # sqlite3
 638                squall -f $1
 639                ;;
 640            *) # default
 641                bat $1
 642                ;;
 643        esac
 644    }
 645    
 646    mp(){ ## media player front end
 647        FZF_DEFAULT_OPTS="--ansi  "
 648        # Use: mp {optional file}
 649        [ "$1" == "-d" ] && cd ~/Downloads  # jump to download directory
 650        [ -z $DISPLAY ] || WINDOW=$(xdotool getactivewindow 2>/dev/null) # get window ID
 651        clear
 652        if [ -f "$1" ]  # if you give it a file run it, else display a list
 653        then
 654            CHOICE="$1"
 655        else
 656            xtitle "mp: Name sort" 
 657            CHOICE=$(lm|fzf --reverse --ansi --color fg:-1,bg:-1,hl:46,fg+:40,bg+:233,hl+:46 --color prompt:166,border:46 --height 70%  --border=rounded --prompt="" --pointer="" --marker="")
 658        fi
 659        EXT="${CHOICE##*.}"
 660        [ "$EXT" == "mp3" ] && FILE=$(echo $CHOICE|cut -d ' ' -f5)
 661        [ "$EXT" == "mp4" ] && FILE=$(echo $CHOICE|cut -d ' ' -f4)
 662        if [ ! -z $FILE ]
 663        then
 664            if [ ! -z $DISPLAY ] 
 665            then
 666                xtitle "$FILE"
 667                echo -n "Playing: $FILE "
 668                xdotool windowminimize $WINDOW
 669                xfconf-query --channel=xfwm4 --property=/general/use_compositing --type=bool --toggle
 670                spinit vlc --play-and-exit $FILE 1>&2 2>/dev/null
 671                xdotool windowactivate $WINDOW
 672                xfconf-query --channel=xfwm4 --property=/general/use_compositing --type=bool --toggle
 673                if [ -f $FILE -a "$(pwd)" == "/home/mitch/Downloads" ]  || [ "$(pwd)" == "/var/hold/Downloads" ] 
 674                then
 675                    clear
 676                    read -p "${BR}Remove:${BY} ${FILE}?${N} " -n 1 DEL
 677                    if [ "$DEL" == "y" ] 
 678                    then
 679                        rm $FILE 
 680                    fi
 681                    bl
 682                    if [ -f $FILE ] 
 683                    then
 684                        read -p "${BR}Upload:${BY} ${FILE}?${N} " -n 1 DEL
 685                        [ "$DEL" == "y" ] && ul $FILE 
 686                    fi
 687                    bl
 688                    if [ -f $FILE ]
 689                    then
 690                        bl
 691                        read -p "${BY}mv${N} $FILE to ~/Temp? " -n 1 MV
 692                        [ "$MV" == "y" ] && mv $FILE ~/Temp
 693                    fi
 694                fi
 695                if [ "$1" == "-n" ]
 696                    then
 697                        clear
 698                        [[ $(\ls -A *.mp? 2>/dev/null) ]] && llm || echo "No files"
 699                    else  
 700                        clear
 701                        [[ $(\ls -A *.mp? 2>/dev/null) ]] && llm -t || echo "No files"
 702                fi
 703            else
 704                echo "$FILE not played, no DISPLAY"
 705            fi
 706        fi
 707    }
 708    
 709    pause(){
 710        [ "$DEBUG" == "1" ] && set -x;
 711        [ "$1" == "-nt" ] && TMOUT="" && shift;
 712        echo "$BY";
 713        if [ $# -gt 0 ]; then
 714            read -t $1 -r -p "${C}Hit any key (${BY}$1${C} second timeout)${N}" -n 1 FOO;
 715        else
 716            read -r -p "${C}Hit any key${N}" -n 1 FOO;
 717        fi;
 718        bl
 719    }
 720    
 721    r(){ # r run it!
 722        # Use: r {optional pattern: p*}
 723        if [ $(\ls -F|grep -c '\*') -lt 1 ] 
 724        then
 725            echo "${BY}Nothing to do${N}"
 726        else
 727            CHOICE=$(\ls -F "$@" | grep '*$' |tr -d '*' |fzf --ansi --reverse --color fg:-1,bg:-1,hl:46,fg+:40,bg+:233,hl+:46 --color prompt:166,border:46 --height 70%  --border=sharp --prompt="" --pointer="" --marker="")
 728            if [ ! -z "$CHOICE" ] 
 729            then
 730                tldr $CHOICE 2> /dev/null | tail -n +3
 731                read -p "${BG}${CHOICE} ${N}" ARGS
 732                ./${CHOICE} $ARGS
 733            fi
 734        fi
 735    }
 736    
 737    rcf() { ## Function to set random background and foreground colors with contrast       # Use: rcf "string"
 738    
 739        # Generate random 1-6 for fg/bg to ensure contrast (avoiding 0/7/8)
 740        local fg=$(( (RANDOM % 6) + 1 ))
 741        local bg=$(( (RANDOM % 6) + 1 ))
 742    
 743        # Ensure background is not too similar to foreground
 744        while [ $fg -eq $bg ]; do
 745            bg=$(( (RANDOM % 6) + 1 ))
 746        done
 747    
 748        # Apply colors and print
 749        tput setaf $fg
 750        tput setab $bg
 751        tput bold # Make text bold for better readability
 752        echo -n " $1 "
 753        tput sgr0 # Reset colors
 754        echo ""
 755    }
 756    
 757    recover(){ ## vim recover from backup dir
 758        if [ -f "$1" ] 
 759        then
 760            FILE="$(pwd)/$1"
 761            cd ~/vim/backup
 762            CHOICE=$(\ls -a |fzf -m --ansi --color fg:-1,bg:-1,hl:46,fg+:40,bg+:233,hl+:46 --color prompt:166,border:46 --height 70%  --border=sharp --prompt="" --pointer="" --marker="" --preview '(highlight -O ansi {} || bat -p {}) 2> /dev/null | head -500')
 763            vimdiff "$FILE" "$CHOICE"
 764        else
 765            echo "recover {file}"
 766            echo "
 767    vimdiff commands
 768    
 769    ]c :         - next difference
 770    [c :         - previous difference
 771    do           - diff obtain
 772    dp           - diff put
 773    zo           - open folded text
 774    zc           - close folded text
 775    :diffupdate  - re-scan the files for differences
 776    :set mouse=a - use mouse click to switch windows
 777    CTRL-W =     - resize windows the same
 778    CTRL-W w     - switch window
 779    "
 780        fi
 781        cd ${OLDDIR}
 782    }
 783    
 784    rs(){ ## restart shell with option to edit .bashrc
 785        # Use: rs (if anything is passed it will edit .bashrc file 1st)
 786        THEME="zenburn" # bat --list-themes
 787        if [ $# -gt 0 ]
 788        then
 789            play -q ~/Music/sounds/system/message-new-instant.oga 2>/dev/null
 790            vim ~/.bashrc
 791            sed -i -e "3s/.*/# Updated....: $(date)/" ~/.bashrc
 792            # bashrc
 793            log "Updated ~/.bashrc"
 794            bat --color=always --theme $THEME ~/.bashrc | aha -b -w -t "~/.bashrc" >/var/www/unix/bashrc.html
 795            cp  ~/.bashrc /var/www/unix/bashrc
 796    
 797            # vimrc - Added to make sure the Web versions were up to date.
 798            sed -i -e "3s/.*/\" Updated....: $(date)/" ~/.vimrc
 799            bat --color=always --theme $THEME ~/.vimrc | aha -b -w  -t "~/.vimrc" >/var/www/unix/vimrc.html
 800            cp  ~/.vimrc /var/www/unix/vimrc
 801    
 802            log "Restart: $$"
 803            exec bash
 804        else
 805            log "Restart: $$"
 806            reset; exec bash
 807        fi
 808    }
 809    
 810    rss(){ ## quick rss url reader
 811        # Use: rss {URL} {Count, defaults to 10}
 812        [ "$#" -eq 2 ] && COUNT=$2 || COUNT=10    
 813    lynx -stdin <<RSSEND
 814    <p>rss "$1"
 815    </p>
 816    
 817    $(rsstail --nofail --time-format '%r %m/%d/%Y' --initial $COUNT -e 1 --format '[{title}]({link}) {updated:>10}  \n' "$1"  |pandoc -t html)
 818    
 819    RSSEND
 820    }
 821    
 822    scale(){ ## change to 640x480
 823        (xterm -geometry 140x4+0+900 -hold -e ~/bin/scale $1 &)
 824    }
 825    
 826    sconky(){ ## re-start conky
 827        # Use: sconky (if anything is passed it will edit config file 1st)
 828        pkill conky
 829        spinit sleep 3
 830        (conky -d -c ~/.conkyrc)
 831        /home/mitch/bin/now-clocking-main/start.sh 2>&1
 832    
 833    }
 834    
 835    tab() { ## run command in new tab
 836    xfce4-terminal --tab --geometry=100x27 -T "$*" --active-tab -x "$*"
 837    }
 838    
 839    tunes(){ ## play my music
 840    SDIR=$(pwd)
 841    cd ~/Music/gospel/kjv
 842    \rm *mp3
 843    cd ~/Music/kjv-verses
 844    for VERSE in $(\ls |shuf -n 20)
 845    do
 846        cp $VERSE ~/Music/gospel/kjv
 847    done
 848    cd ~/Music && find gospel/ -name '*.mp3' >tunes.m3u 
 849    xtitle "Playing music"
 850    xfce4-terminal --tab --geometry=100x27 --title="Tunes" --active-tab -x nvlc -Z tunes.m3u
 851    cd $SDIR
 852    clear
 853    }
 854    
 855    xtitle(){ ## set window title
 856        # Use: xtitle "Text to display"
 857        printf "\033]0;%s\007" "${*}🌀${HOSTNAME}"
 858    }
 859    
 860    
 861    # Ending
 862    # ======
 863    clear
 864    if [ "$LOGNAME" == "mitch" ]
 865    then
 866        play -q ~/Music/system/outcome-success.oga 2>/dev/null
 867        uptime
 868        status
 869        now -s
 870    else
 871        log "Switching to root"
 872        echo "${BY}sudo: ${BR}switched to root$N"
 873        HISTFILE=/.root.hist        # keeps it out of mine
 874        TMOUT=600                   # Close terminal after 10 minutes of inactivity
 875        echo "Window timeout in: ${BY}$TMOUT seconds${N}"
 876        export PS1='ES:$(success_indicator) $(printf "\033]0;🌀\h:\w \007")L:${BY}$SHLVL${N} J:${BY}\j${N} ${BY}[\u🌀\h] $(edir)\w${N}\n${BR}#${N} '
 877    fi
 878    
 879    [ -f ~/.fzf.bash ] && source ~/.fzf.bash
 880    
 881    
───────┴────────────────────────────────────────────────────────────────────────