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