a few new functions
[distro-setup] / .bashrc
diff --git a/.bashrc b/.bashrc
index f9e2305f490565386ba06e767f178bd2fb766aeb..3725a9f1a56594f2fc3ae7998db933b9ffcd4d52 100644 (file)
--- a/.bashrc
+++ b/.bashrc
@@ -1,3 +1,17 @@
+# Copyright (C) 2016 Ian Kelling
+
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+
+#     http://www.apache.org/licenses/LICENSE-2.0
+
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
 # to debug
 #set -x
 # redirect output to log file. this doesn't work. todo figure out why
@@ -25,6 +39,7 @@
 # assume we want ssh commands to source this file if we are sourcing it,
 # and we haven't specified otherwise already
 [[ ! $BASH_LOGIN_SHELL ]] && export BASH_LOGIN_SHELL=true
+#BASH_LOGIN_SHELL=false # temporary override
 
 # first conditions show that we are an ssh command without an interactive shell
 if [[ $SSH_CONNECTION ]] \
@@ -66,7 +81,9 @@ unalias -a
 # use extra globing features.
 shopt -s extglob
 # include .files when globbing, but ignore files name . and ..
-# setting this also sets dotglob
+# setting this also sets dotglob.
+# Note, this doesn't work in bash 4.4 anymore, for paths with
+# more than 1 directory, like a/b/.foo, since * is fixed to not match /
 export GLOBIGNORE=*/.:*/..
 
 # broken with bash_completion package. Saw a bug for this once. Don't anymore.
@@ -96,15 +113,16 @@ shopt -s histappend
 shopt -s checkwinsize
 # attempt to save multiline single commands as single history entries.
 shopt -s cmdhist
+# enable **
 shopt -s globstar
 
 
 # inside emacs fixes
-if [[ $INSIDE_EMACS ]]; then
+if [[ $RLC_INSIDE_EMACS ]]; then
     # EMACS is used by bash on startup, but we don't need it anymore.
     # plus I hit a bug in a makefile which inherited it
     unset EMACS
-    export INSIDE_EMACS
+    export RLC_INSIDE_EMACS
     export PAGER=cat
     export MANPAGER=cat
     # scp completion does not work, but this doesn't fix it. todo, figure this out
@@ -137,7 +155,7 @@ fi
 
 if [[ $- == *i* ]]; then
     # for readline-complete.el
-    if [[ $INSIDE_EMACS ]]; then
+    if [[ $RLC_INSIDE_EMACS ]]; then
         # all for readline-complete.el
         stty echo
         bind 'set horizontal-scroll-mode on'
@@ -195,16 +213,14 @@ C_DEFAULT_DIR=/a
 ###################
 ## include files ###
 ###################
-
-for _x in /a/bin/distro-functions/src/* /a/bin/*/*-function; do
+for _x in /a/bin/distro-functions/src/* /a/bin/!(githtml)/*-function?(s); do
     source "$_x"
 done
 unset _x
 # so I can share my bashrc
-for x in /a/bin/bash_unpublished/*; do source $x; done
+for x in /a/bin/bash_unpublished/source-!(.#*); do source $x; done
 source $(dirname $(readlink -f $BASH_SOURCE))/path_add-function
 source /a/bin/log-quiet/logq-function
-source /a/bin/log-once/log-once-function
 path_add /a/exe
 path_add --ifexists --end /a/opt/adt-bundle*/tools /a/opt/adt-bundle*/platform-tools
 # todo, these need to be renamed to be less generic.
@@ -212,6 +228,7 @@ path_add --ifexists --end /a/opt/adt-bundle*/tools /a/opt/adt-bundle*/platform-t
 #path_add $HOME/bin/bash-programs-by-ian/utils
 
 
+
 ###############
 ### aliases ###
 ###############
@@ -246,7 +263,6 @@ unalias ls ll grep &>/dev/null ||:
 
 
 
-
 #####################
 ###  functions   ####
 #####################
@@ -302,7 +318,7 @@ _cdiff-prep() {
 
 _khfix_common() {
     local h=${1##*@}
-    ssh-keygen -R $h
+    ssh-keygen -R $h -f $(readlink -f ~/.ssh/known_hosts)
     local x=$(timeout 0.1 ssh -v $1 |& sed -rn "s/debug1: Connecting to $h \[([^\]*)].*/\1/p");
     ssh-keygen -R $x -f $(readlink -f ~/.ssh/known_hosts)
 }
@@ -321,6 +337,13 @@ a() {
 
 ack() { ack-grep "$@"; }
 
+astudio() {
+    # googling android emulator libGL error: failed to load driver: r600
+    # lead to http://stackoverflow.com/a/36625175/14456
+    export ANDROID_EMULATOR_USE_SYSTEM_LIBS=1
+    /a/opt/android-studio/bin/studio.sh "$@" &r;
+}
+
 bashrcpush () {
     local startdir="$PWD"
     cd ~
@@ -329,7 +352,7 @@ bashrcpush () {
         tar cz bin/semi-private bin/distro-functions/src | ssh $x tar xz
     done
     cd $(mktemp -d)
-    command cp /a/c/repos/bash/!(.git) ~/.gitconfig .
+    command cp /a/c/repos/bash/!(.git|..|.) ~/.gitconfig .
     for x in "$@"; do
         tar cz * | ssh $x tar xz
     done
@@ -372,15 +395,22 @@ cdiff() {
     done < "$unified"
 }
 
-cgpl ()
+cgpl()
 {
-    if [[ $# == 0 ]]; then
+    if (($#)); then
+        cp /a/bin/data/COPYING "$@"
+    else
         cp /a/bin/data/COPYING .
+    fi
+}
+capache()
+{
+    if (($#)); then
+        cp /a/bin/data/LICENSE "$@"
     else
-        cp /a/bin/data/COPYING "$@"
+        cp /a/bin/data/LICENSE .
     fi
 }
-
 chown() {
     # makes it so chown -R symlink affects the symlink and its target.
     if [[ $1 == -R ]]; then
@@ -558,6 +588,9 @@ rename-test() {
     return 0
 }
 
+feh() {
+    command feh -FzZ "$@"
+}
 
 funce() {
     # like -e for functions. returns on error.
@@ -574,6 +607,30 @@ fw() {
     firefox -P default "$@" >/dev/null 2>&1
 }
 
+getdir () {
+    local help="Usage: getdir [--help] PATH
+Output the directory of PATH, or just PATH if it is a directory."
+    if [[ $1 == --help ]]; then
+        echo "$help"
+        return 0
+    fi
+    if [[ $# -ne 1 ]]; then
+        echo "getdir error: expected 1 argument, got $#"
+        return 1
+    fi
+    if [[ -d $1 ]]; then
+        echo "$1"
+    else
+        local dir="$(dirname "$1")"
+        if [[ -d $dir ]]; then
+            echo "$dir"
+        else
+            echo "getdir error: directory does not exist"
+            return 1
+        fi
+    fi
+}
+
 git_empty_branch() { # start an empty git branch. carefull, it deletes untracked files.
     [[ $# == 1 ]] || { echo 'need a branch name!'; return 1;}
     local gitroot
@@ -584,13 +641,32 @@ git_empty_branch() { # start an empty git branch. carefull, it deletes untracked
     git clean -fdx
 }
 
-gr() {
-    grep -iIP --color=auto "$@"
-}
+gitroot() {
+    local help="Usage: gitroot [--help]
+Print the full path to the root of the current git repo
 
+Handles being within a .git directory, unlike git rev-parse --show-toplevel,
+and works in older versions of git which did not have that."
+    if [[ $1 == --help ]]; then
+        echo "$help"
+        return
+    fi
+    local p=$(git rev-parse --git-dir) || { echo "error: not in a git repo" ; return 1; }
+    [[ $p != /* ]] && p=$PWD
+    echo "${p%%/.git}"
+}
 
+# quit will prompt if the program crashes.
+gmacs() { gdb -ex=r -ex=quit --args emacs "$@"; r; }
 
+gse() {
+    git send-email --notes '--envelope-sender=<ian@iankelling.org>' \
+        --suppress-cc=self "$@"
+}
 
+gr() {
+    grep -iIP --color=auto "$@"
+}
 
 grr() {
     if [[ ${#@} == 1 ]]; then
@@ -600,6 +676,18 @@ grr() {
     fi
 }
 
+hstatus() {
+    # do git status on published repos
+    cd /a/bin/githtml
+    for x in !(forks) forks/* ian-specific/*; do
+        cd `readlink -f $x`/..
+        hr
+        echo $x
+        i status
+        cd /a/bin/githtml
+    done
+}
+
 hl() { # history limit. Write extra history to archive file.
     # todo: this is not working or not used currently
     local max_lines linecount tempfile prune_lines x
@@ -648,9 +736,10 @@ ic() {
 }
 
 
-ifn () {
+ifn() {
     # insensitive find
-    find -L . -iname "*$**" 2>/dev/null
+    find -L . -not \( -name .svn -prune -o -name .git -prune \
+         -o -name .hg -prune \) -iname "*$**" 2>/dev/null
 }
 
 
@@ -732,12 +821,6 @@ make-targets() {
 }
 
 
-md5diff() {
-    [[ $(md5sum < "$1") != $(md5sum < "$2") ]]
-}
-
-
-
 mkc() {
     mkdir "$1"
     c "$1"
@@ -803,7 +886,7 @@ whatismyip() { pubip; }
 
 
 pwgen() {
-    apg -s -m 10 -x 14 -t
+    apg -m 12 -x 16 -t
 }
 
 
@@ -852,7 +935,8 @@ rlu() { # [OPTS] HOST PATH
 }
 
 
-rspicy() { # HOST DOMAIN
+rspicy() { # usage: HOST DOMAIN
+    # connect to spice vm remote host. use vspicy for local host
     local port=$(ssh $1<<EOF
 sudo virsh dumpxml $2|grep "<graphics.*type='spice'" | \
        sed -rn "s/.*port='([0-9]+).*/\1/p"
@@ -867,12 +951,8 @@ EOF
 
 s() {
     # background
-    # alias s='SUDOD="$PWD" sudo -i '
-    # because this is an alias, and the extra space at the end, it would allow
-    #  aliases to be used with it. but aliases aren't used in scripts,
-    #  better to eliminate inconsistencies. Plus, you can't do s=s; $s command
-    #  with an alias, which I like to do in some functions
-    # extra space at the end allows aliases to work
+    # I use a function because otherwise we can't use in a script,
+    # can't assign to variable.
     #
     # note: gksudo is recommended for X apps because it does not set the
     # home directory to the same, and thus apps writing to ~ fuck things up
@@ -907,6 +987,13 @@ sb() { # sudo bash -c
 }
 complete -F _root_command s sb
 
+scssl() {
+    # s gem install scss-lint
+    pushd /a/opt/thoughtbot-guides
+    git pull --stat
+    popd
+    scss-lint -c /a/opt/thoughtbot-guides/style/sass/.scss-lint.yml "$@"
+}
 
 ser() {
     local s; [[ $EUID != 0 ]] && s=sudo
@@ -984,8 +1071,12 @@ t() {
     local x
     local -a args
     if type -t trash-put >/dev/null; then
-        # skip args that don't exist, or else it's an err
-        for x in "$@"; do [[ ! -e $x ]] || args+=("$x"); done
+        # skip args that don't exist, or else trash-put will have an error
+        for x in "$@"; do
+            if [[ -e $x || -L $x ]]; then
+                args+=("$x")
+            fi
+        done
         [[ ! ${args[@]} ]] || trash-put "${args[@]}"
     else
         rm -rf "$@"
@@ -1039,7 +1130,7 @@ te() {
 
 tm() {
     # timer in minutes
-    (sleep $(calc "$@ * 60") && mpv --volume 50 /a/bin/data/alarm.mp3) > /dev/null 2>&1 &
+    (sleep $(calc "$@ * 60") && mpv --volume 50 /a/bin/data/alarm.mp3 --loop=no) > /dev/null 2>&1 &
 }
 
 ts() { # start editing a new file
@@ -1100,26 +1191,36 @@ vc() {
     # until I get it all wired up with systemd.
     newns vpn start
     pid=$(< /run/openvpn/client.pid)
-    if [[ ! $pid ]]; then
-        s ip netns exec vpn /usr/sbin/openvpn --daemon ovpn --config /etc/openvpn/client.conf --cd /etc/openvpn --writepid /run/openvpn/client.pid
-    elif [[ ! -e /proc/$pid ]]; then
-        echo "$0: ERROR: pidfile pid $pid is not a process!!!"
-        return 1
+    vpn_on=false
+    if [[ $pid ]]; then
+        if [[ -e /proc/$pid ]]; then
+            vpn_on=true
+        else
+            vpn_on=false
+            s rm -f /run/openvpn/client.pid
+        fi
     fi
+    $vpn_on || s ip netns exec vpn /usr/sbin/openvpn --daemon ovpn --config /etc/openvpn/client.conf --cd /etc/openvpn --writepid /run/openvpn/client.pid
     gksudo -- ip netns exec vpn gksudo -u ${SUDO_USER:-$USER} "$@"
 }
 
 transmission() {
     vc transmission-gtk&
     i=0
-    while ((i < 10)); do
+    while true; do
+        if ((i > 10)); then
+            echo "$0: error: vpn tun0 didn't show up"
+            return 1
+        fi
         tun_ip=$(s ip netns exec vpn ip a show dev tun0 | sed -rn 's/^ *inet (10\.8\.\S+).*/\1/p')
         [[ ! $tun_ip ]] || break
         sleep 1
+        i=$((i + 1))
     done
     echo "$0: tun_ip=$tun_ip"
     [[ $tun_ip ]] || { e "$0: error: no tun0 addr found"; return 1; }
     ssh dopub bash <<EOF
+set -e
 rule="-A PREROUTING -i eth0 -p tcp -m tcp --dport 63324 -j DNAT --to-destination $tun_ip:63324"
 found=false
 while read -r line; do
@@ -1175,7 +1276,7 @@ vrm() {
 
 
 
-vspicy() {
+vspicy() { # usage: VIRSH_DOMAIN
     # connect to vms made with virt-install
     spicy -p $(sudo virsh dumpxml "$1"|grep "<graphics.*type='spice'"|\
                    sed -r "s/.*port='([0-9]+).*/\1/")
@@ -1289,7 +1390,7 @@ if [[ $- == *i* ]]; then
     shopt -s autocd
     shopt -s dirspell
     PS1='\w'
-    if [[ $- == *i* ]]  && [[ ! $INSIDE_EMACS ]]; then
+    if [[ $- == *i* ]]  && [[ ! $RLC_INSIDE_EMACS ]]; then
         PROMPT_DIRTRIM=2
        bind -m vi-command B:shell-backward-word
        bind -m vi-command W:shell-forward-word
@@ -1342,8 +1443,6 @@ fi
 
 
 
-
-
 ###########################################
 # stuff that makes sense to be at the end #
 ###########################################
@@ -1393,11 +1492,22 @@ fi
 
 path_add --end ~/.npm-global
 
+
+# didn't get drush working, if I did, this seems like the
+# only good thing to include for it.
+# Include Drush completion.
+# if [ -f "/home/ian/.drush/drush.complete.sh" ] ; then
+#     source /home/ian/.drush/drush.complete.sh
+# fi
+
+
 # https://wiki.archlinux.org/index.php/Xinitrc#Autostart_X_at_login
 # i added an extra condition as gentoo xorg guide says depending on
 # $DISPLAY is fragile.
 if [[ ! $DISPLAY && $XDG_VTNR == 1 ]] && shopt -q login_shell && isarch; then
     exec startx
 fi
+
+
 # ensure no bad programs appending to this file will have an affect
 return 0