changeset 339:99f8142078c7

wtf
author Jeff Hammel <jhammel@mozilla.com>
date Wed, 19 Jun 2013 10:58:18 -0700
parents 5438630e118c (diff) 9e5563ca20da (current diff)
children 576edf9dee2e
files .bashrc
diffstat 39 files changed, 1036 insertions(+), 461 deletions(-) [+]
line wrap: on
line diff
--- a/.bash_overrides	Wed May 16 08:58:47 2012 -0700
+++ b/.bash_overrides	Wed Jun 19 10:58:18 2013 -0700
@@ -1,43 +1,10 @@
 #!/bin/bash
 
-function unlink {	
-    command unlink `echo $@ | sed 's/\/$//g'`
-}
-
-function find {
-
-    if (( ! $# ))
-    then
-	return
-    fi
-    
-    if [ -d $1 ]
-    then
-	DIR="$1"
-	shift
-    else
-	DIR="$PWD"
-    fi
-    
-    if [ "$#" == "1" ]
-    then
-	`which find` -L "$PWD" -not -path '*.svn*' -iname "$1"
-	return 0
-    fi
-
-    COMMAND="`which find` -L \"$DIR\" -not -path '*.svn*' $@"
-#echo $COMMAND # for debugging
-    `which find` -L "$DIR" -not -path '*.svn*' "$@"
-}
+### command overrides too elaborate for aliases
 
 cd() {
-    
+
     ENV=""
-    # find if you're in a
-    if [ -n "${WORKING_ENV}" ]
-    then
-	ENV="${WORKING_ENV}"
-    fi
     if [ -n "${VIRTUAL_ENV}" ]
     then
 	ENV="${VIRTUAL_ENV}"
@@ -45,7 +12,7 @@
 
 
     if [ -d "$@" ]
-    then		
+    then
 	command cd "$@"
     else
 	if [ -e "$@" ]
@@ -73,18 +40,13 @@
 		    deactivate
 		fi
 	    else
-		return 
+		return
 	    fi
 	fi
 	source "bin/activate"
     fi
 
     ENV=""
-    # find if you're in a
-    if [ -n "${WORKING_ENV}" ]
-    then
-	ENV="${WORKING_ENV}"
-    fi
     if [ -n "${VIRTUAL_ENV}" ]
     then
 	ENV="${VIRTUAL_ENV}"
@@ -94,7 +56,7 @@
     then
 	FULLPWD=$(python -c 'import os; print os.getcwd()')
 	if (( ! `expr match "${FULLPWD}" "${ENV}"` ))
-	then 
+	then
 	    if [[ -n "`type -t deactivate`" ]]
 	    then
 		deactivate
@@ -104,6 +66,49 @@
     unset ENV
 }
 
-emacsclient() {
+function emacsclient() {
     command emacsclient $@ > /dev/null &
 }
+
+function find {
+
+    if (( ! $# ))
+    then
+	command find
+        return
+    fi
+
+    if [ -d $1 ]
+    then
+	DIR="$1"
+	shift
+    else
+	DIR="$PWD"
+    fi
+
+    if [ "$#" == "1" ]
+    then
+	`which find` -L "$PWD" -not -path '*.svn*' -iname "$1"
+	return 0
+    fi
+
+    COMMAND="`which find` -L \"$DIR\" -not -path '*.svn*' $@"
+#echo $COMMAND # for debugging
+    `which find` -L "$DIR" -not -path '*.svn*' "$@"
+}
+
+function lsdiff {
+    # TODO: extract this general pattern as a bash "decorator"
+    if expr "$1" : 'http[s]\?://.*' &> /dev/null
+    then
+        curl --location "$1" 2> /dev/null | command lsdiff
+    else
+        command lsdiff "$@"
+    fi
+
+}
+
+function unlink {
+    command unlink `echo $@ | sed 's/\/$//g'`
+}
+
--- a/.bashrc	Wed May 16 08:58:47 2012 -0700
+++ b/.bashrc	Wed Jun 19 10:58:18 2013 -0700
@@ -1,39 +1,55 @@
-source /etc/profile
+#!/bin/bash
+### bash rc file ###
+
+# so
+PROFILE=/etc/profile
+if [ -e "${PROFILE}" ]
+then
+    . "${PROFILE}"
+fi
 
 # 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
+    # Shell is non-interactive.  Be done now!
+    return
 fi
 
 # Enable colors for ls, etc.  Prefer ~/.dir_colors #64489
 if [[ -f ~/.dir_colors ]] ; then
-	eval $(dircolors -b ~/.dir_colors)
+    eval $(dircolors -b ~/.dir_colors)
 elif [[ -f /etc/DIR_COLORS ]] ; then
-	eval $(dircolors -b /etc/DIR_COLORS)
+    eval $(dircolors -b /etc/DIR_COLORS)
 fi
 
 # variables
+export BROWSER=$(which firefox)
 export CLICOLOR=1
 export EDITOR='emacs -nw'
+export JS_EDITLINE=1
 export MOZCONFIG=~/mozilla/mozconfigs/mozconfig
 export MOZSOURCE=~/mozilla/src/mozilla-central
 export MOZOBJ=~/mozilla/src/obj-browser
 export JS_EDITLINE=1
 
 # aliases
-alias ls='ls --color=auto'
-alias grep='grep --colour=auto'
-alias wget='wget --no-check-certificate'
+alias awd="python -c 'import os;  print os.path.realpath(\".\")'"
+alias currentpatch='echo `hg root`/.hg/patches/`hg qapp -v | head -n 1 | cut -f 3 -d " "`'
 alias datestamp='date +%Y%m%d%H%M%S'
-alias svnst='svn st | grep -v "^\?"'
-alias awd="python -c 'import os;  print os.path.realpath(\".\")'"
 alias distribute='python setup.py egg_info -RDb "" sdist register upload'
+alias grep='grep --colour=auto'
+alias ls='ls --color=auto'
 alias random="python -c 'import sys, random; foo = sys.argv[1:]; random.shuffle(foo); print \" \".join(foo)'"
+alias weekstamp="date --date=\"$((`date '+%u'`-1)) days ago\" '+%b %d'"
+alias wget='wget --no-check-certificate'
 alias xpcshell="LD_LIBRARY_PATH=${MOZOBJ}/dist/bin ${MOZOBJ}/dist/bin/xpcshell"
+
+# bzconsole aliases for filing bugs
+alias mozbase-bug="bz new Mozbase --cc ':wlach'"
+alias mozbuild-bug="bz new --product Core 'Build Config' --cc ':gps'"
 alias mozharness-bug="bz new 'Release Engineering: Automation (General)' --cc ':aki' --whiteboard 'mozharness'"
+alias releng-bug="bz new 'Release Engineering: Automation (General)'"
 alias talos-bug="bz new Talos --cc ':jmaher' --cc ':BYK'"
 
 # PROMPT
@@ -42,30 +58,67 @@
 PROMPT_COMMAND='echo -ne "\033]0;${SSH_CLIENT/*/$HOSTNAME:}${PWD/~/~}\007"'
 
 # PATHs
-export PATH=~/firefox:~/bin:~/python:$PATH:/usr/sbin:/usr/games/bin
+export PATH=~/firefox:~/bin:~/bin/mozilla:~/python:$PATH:/usr/sbin:/usr/games/bin
 export PYTHONPATH=~/python:$PYTHONPATH:~/virtualenv
 
-
 ### functions
 
+apply-patch() {
+    # apply a patch
+    # TODO:
+    # - rewrite in python!
+    # - extract this general pattern as a bash "decorator" like `lsdiff` in .bash_overrides
+    # - right now level=1; make this configurable (somehow)
+
+    if (( ! $# ))
+    then
+        echo "No patch supplied"
+        return 1
+    fi
+
+    for patch in $@
+    do
+        if expr "$1" : 'http[s]\?://.*' &> /dev/null
+        then
+            IS_URL="true"
+        else
+            IS__URL="false"
+        fi
+
+        if [[ ${IS_URL} == "true" ]]
+        then
+            if curl --location "${patch}" 2> /dev/null | (command patch -p1 --dry-run &> /dev/null)
+            then
+                curl --location "${patch}" 2> /dev/null | command patch -p1
+                continue
+            else
+                echo "curl --location ${patch} 2> /dev/null | command patch -p1 --dry-run"
+                curl --location "${patch}" 2> /dev/null | command patch -p1 --dry-run
+                return $?
+            fi
+        else
+            if patch -p1 --dry-run < ${patch}
+            then
+                patch -p1 < ${patch}
+                continue
+            else
+                echo "patch -p1 --dry-run < ${patch}"
+                patch -p1 --dry-run < ${patch}
+                return $?
+            fi
+        fi
+    done
+}
+
 cdwin() {
-# change directory to a window's location using its title
+    # change directory to a window's location using its title,
+    # as that is set to the cwd by PS1 [?]
+    # TODO: ssh windows
     DIR=$(xwininfo | dictify.py xwininfo | awk '{ print $NF }' | sed 's/"//g')
     DIR=${DIR/\~/$HOME}
     cd $DIR
 }
 
-eend() {
-# edit the end of a file with emacs
-    FILE=$1
-    shift
-    emacs +`wc -l "$FILE"` $@
-}
-
-git-diff-master() {
-git diff $(git merge-base HEAD master)
-}
-
 function colors() {
 
     CLR_WHITE="\033[0;37m"
@@ -88,9 +141,21 @@
 }
 colors
 
-# nice fast find function
-EXCLUDES="(\.svn)|(\.mo$)|(\.po$)|(\.pyc$)"
+eend() {
+    # edit the end of a file with emacs
+    FILE=$1
+    shift
+    emacs +`wc -l "$FILE"` $@
+}
+
+git-diff-master() {
+    # differences of a git repository with master
+    git diff $(git merge-base HEAD master)
+}
+
+EXCLUDES="(\.svn)|(\.mo$)|(\.po$)|(\.pyc$)|(\.hg$)|(\.git$)"
 ff() {
+    # nice fast find function
 
     if (( $# < 2 ))
     then
@@ -105,9 +170,11 @@
 }
 
 chainff() {
+    # chained fast find
+
     if (( $# < 2 ))
     then
-	return 0
+	return 1 # bad invocation
     fi
 
     RESULTS=`ff "$2" "$1"`
@@ -121,7 +188,7 @@
 	    then
 		touch /dev/null
 	    else
-		i=""		
+		i=""
 		break
 	    fi
 	done
@@ -132,9 +199,9 @@
     done
 }
 
-# contextual fastfind
+
 cff () {
-
+    # contextual fastfind
     if (( $# < 2 )); then
         local FILENAME='*' # default -- look in all files
     else
@@ -146,43 +213,63 @@
         grep --color=auto -i -n -C 3 "$1" $i
     done
 
-} 
+}
 
-# make a temporary file
 tmpfile() {
+    # make a temporary file if `tempfile` not available
 
-if [ "$#" == "0" ]
-then
-    args="tmp"
-else
-    args=$@
-fi
+    if [ "$#" == "0" ]
+    then
+        args="tmp"
+    else
+        args=$@
+    fi
 
-for i in $args
-do
-    NEWNAME=${i}.$RANDOM
+    for i in $args
+    do
+        NEWNAME=${i}.$RANDOM
 
-    while [ -e $NEWNAME ]
-    do
-	NEWNAME=${NEWNAME}.tmp
+        while [ -e $NEWNAME ]
+        do
+	    NEWNAME=${NEWNAME}.tmp
+        done
+        echo "$NEWNAME"
     done
-    echo "$NEWNAME"
-done
 }
 
 edpe() {
-# edit and pipe the buffer to stdout
-FILE=`tmpfile`
-$EDITOR $FILE
-cat $FILE
-rm $FILE
+    # edit and pipe the buffer to stdout
+    FILE=`tmpfile`
+    $EDITOR $FILE
+    cat $FILE
+    rm $FILE
+}
+
+isrunning() {
+    # is a process running? (by name)
+    # see also: talos for a better version
+    for i in "$@"
+    do
+	ps axwww  | grep "$i" | grep -v 'grep'
+    done | sort | uniq
+
+}
+
+killbyname() {
+    # kill a process by name
+    kill `isrunning "$@" | awk '{ print $1 }' | onelineit.py`
+}
+
+fn() {
+    # full name
+    python -c "import os; print os.path.realpath('$*')"
 }
 
 swap() {
-# swap two files
+    # swap two files
     if [ "$#" != "2" ]
     then
-	echo "Usage: $FUNCNAME <first_arg> <second_arg>"
+	echo "Usage: $FUNCNAME <file1> <file2>"
 	return
     fi
     for i in "$1" "$2"
@@ -195,61 +282,109 @@
     done
 
     NEWNAME=`basename $1`.$RANDOM
-
     while [ -e $NEWNAME ]
     do
 	NEWNAME=${NEWNAME}.tmp
 	echo "$NEWNAME"
     done
 
-    mv `basename $1` $NEWNAME
-    mv `basename $2` `basename $1`
-    mv $NEWNAME `basename $2`
+    mv "$1" "$NEWNAME"
+    mv "$2" "$1"
+    mv "$NEWNAME" "$2"
+}
+
+buffer() {
+  # temporary buffer with cat and /dev/null
+  cat > /dev/null
+}
+
+### `which` commands
+
+realwhich() {
+    # which -> real paths
+    command which $@ | while read line
+    do
+        python -c "import os; print os.path.realpath('${line}')"
+    done
+}
+
+whview() {
+    # which view
+    less `realwhich $@`
+}
+
+whemacs() {
+    # which emacs
+    emacs -nw `realwhich $@`
 }
 
-isrunning() {
-# is a process running? (by name)
-    for i in "$@"
-    do
-	ps axwww  | grep "$i" | grep -v 'grep'
-    done | sort | uniq
+### functions for python
 
+pyfile() {
+    # python file path
+    python -c "import $1; print $1.__file__"
 }
 
-killbyname() {
-# kill a process by name
-    kill `isrunning "$@" | awk '{ print $1 }' | onelineit.py`
+setup-all() {
+    # setup all for development
+    # TODO: flowerbed?
+    for i in *
+    do
+        if [ -e "${i}/setup.py" ]
+        then
+            cd "${i}"
+            python setup.py develop
+            cd ..
+        fi
+    done
 }
 
+recreate-venv() {
+    # recreate a virtualenv
+    VIRTUALENV="virtualenv.py"
+    if ! which ${VIRTUALENV}
+    then
+        return 1
+    fi
+    VENV_PATH=$(which ${VIRTUALENV} &> /dev/null)
+
+    # update virtualenv if possible
+    DIRNAME=$(dirname ${VENV_PATH})
+    if [ -d "${DIRNAME}/.git" ]
+    then
+        cd "${DIRNAME}"
+        git pull
+        cd --
+    fi
+
 
-tf() {
-    if [[ $@ ]]
-    then
-	echo "true"
-    else
-	echo "false"
-    fi
-}
+    # for each virtualenv given...
+    for i in $@
+    do
+        # ...recreate it...
+        ${VIRTUALENV} --clear "${i}"
 
-# full name
-fn() {
-    python -c "import os; print os.path.realpath('$*')"
+        SRCDIR="${i}"/src
+        if [ -d "${SRCDIR}" ]
+        then
+            . "${i}/bin/activate"
+            OLDPWD=${PWD}
+            cd "${SRCDIR}"
+            for j in *
+            do
+                if [ -e "${j}"/setup.py ]
+                then
+                    cd "${j}"
+                    python setup.py develop
+                    cd ..
+                fi
+            done
+            cd "${OLDPWD}"
+        fi
+    done
 }
 
-# which view
-whview() {
-    less `which $@`
-}
-
-# which emacs
-whemacs() {
-    emacs -nw `which $@`
-}
-
-pyfile() {
-# python file name
-python -c "import $1; print $1.__file__"
-}
+### functions for version control systems
 
 svndance(){
 # do the svn import dance!
@@ -266,52 +401,63 @@
 }
 
 difffiles() {
-grep '^+++ ' $@ | sed 's/+++ b\///'
+    grep '^+++ ' $@ | sed 's/+++ b\///'
 }
 
-hg-update-all() { 
-for i in *; 
-do
-    if [ -e $i/.hg ]
-    then
-        cd $i
-        hg pull
-        hg update
-        cd -
-    fi
-done
+hg-update-all() {
+    # update all hg repositories in the current directory
+    for i in *;
+    do
+        if [ -e $i/.hg ]
+        then
+            cd $i
+            hg pull
+            hg update
+            cd -
+        fi
+    done
 }
 
 hg-qcommit() {
-message=$1
-hg qrefresh
-if [ -z "${message}" ]
-then
-    hg qcommit
-else
-    hg qcommit -m "${message}"
-fi
-hgroot=$(hg root)
-patches=${hgroot}/.hg/patches/ 
-if [ -e ${patches}.hg ]
-then
-    cd ${patches}
-    hg push
-fi
-cd -
-}
-
-blog-file() {
-echo "$HOME/web/blog/k0s/entries/public/$1"
+    message=$1
+    hg qrefresh
+    if [ -z "${message}" ]
+    then
+        hg qcommit
+    else
+        hg qcommit -m "${message}"
+    fi
+    hgroot=$(hg root)
+    patches=${hgroot}/.hg/patches/
+    if [ -e ${patches}.hg ]
+    then
+        cd ${patches}
+        hg push
+    fi
+    cd -
 }
 
 hgrc() {
+# write an hgrc file
+# TODO: in the case you're in an `hg root`...what then?
+# - NOTE: /home/jhammel is an `hg root`, so be careful!
+# There should be a way to update $(hg root)/.hg/hgrc automatically
+# Likewise, git
+# Python script? .dotfile?
 ROOT="${1}"
 echo "[paths]"
 echo "default = ${ROOT}"
 echo "default-push = ssh://${ROOT#http*://}"
 }
 
+### functions for web content
+
+blog-file() {
+    echo "$HOME/web/blog/k0s/entries/public/$1"
+}
+
+###
+
 flatten() {
   directory=$PWD
   if [ "$#" == "1" ]
@@ -354,12 +500,30 @@
 
 }
 
+rmktmp() {
+
+TMPDIR=~/tmp
+if [ -e ${TMPDIR} ]
+then
+  rm -rf ${TMPDIR}
+fi
+mkdir ${TMPDIR}
+cd ${TMPDIR}
+pwd
+
+}
+
 ### include overrides for commands
 source ~/.bash_overrides
 
 ### regenerate fluxbox menus here for convenience
 MENU=~/web/site/programs.html
-if [ -e $MENU ]
-then
-    html2flux.py $MENU > ~/.fluxbox/applications
-fi
+regeneratefluxmenu() {
+    if [ -e $MENU ]
+    then
+        # XXX could be safer
+        # XXX ...along with the fluxbox menu option o_O
+        html2flux.py $MENU > ~/.fluxbox/applications
+    fi
+}
+regeneratefluxmenu
--- a/.emacs	Wed May 16 08:58:47 2012 -0700
+++ b/.emacs	Wed Jun 19 10:58:18 2013 -0700
@@ -1,13 +1,52 @@
-(server-start)
+;; ;; ;; emacs server (what a piece of crap)
+;; (require 'server)
+;;   (unless (server-running-p)
+;;     (server-start))
+;; ;; ;; An error has occurred while loading `/home/jhammel/.emacs':
+;; ;; ;; Symbol's function definition is void: server-running-p
+;; ;; ;; To ensure normal operation, you should investigate and remove the
+;; ;; ;; cause of the error in your initialization file.  Start Emacs with
+;; ;; ;; the `--debug-init' option to view a complete error backtrace.
+
+;; ;; ;; For information about GNU Emacs and the GNU system, type C-h C-a.
+;; ;; How to fix:
+;; http://stackoverflow.com/questions/9999320/how-to-check-if-a-function-e-g-server-running-p-is-available-under-emacs
+
+;;;; bars
+
+;; Turn off the status bar and on the mouse if we're not in a window system
+(menu-bar-mode (if window-system 1 -1))
+
+;; no need for a tool bar
 (if (boundp 'tool-bar-mode) (tool-bar-mode 0))
+
+;; ...or a startup message
+;; instead, it'd be nice to start with a list of recent files (recentf)
 (setq inhibit-startup-message t)
+
+;; no f-ing backup files
 (setq make-backup-files nil)
+
+;; show trailing whitespace
+(setq-default show-trailing-whitespace t)
+
+;;;; ??? no idea
+
 (put 'downcase-region 'disabled nil)
 (setq truncate-lines nil)
-(setq truncate-partial-width-windows nil) 
+(setq truncate-partial-width-windows nil)
 (setq use-file-dialog nil)
 
-;; indentation
+;; make directories when they don't exist
+;; from http://stackoverflow.com/questions/6830671/how-to-make-emacs-create-intermediate-dirs-when-saving-a-file
+(add-hook 'before-save-hook
+          (lambda ()
+            (when buffer-file-name
+              (let ((dir (file-name-directory buffer-file-name)))
+                (when (not (file-exists-p dir))
+                  (make-directory dir t))))))
+
+;;;; indentation
 
 ;; python indentation
 (setq python-indent 4)
@@ -26,34 +65,37 @@
 (transient-mark-mode 1)
 
 (put 'upcase-region 'disabled nil)
-;; Show line-number in the mode line
+
+;;;; line/col #s
+;;;; Show line and column numbers in the mode line
 (line-number-mode 1)
-
-;; Show column-number in the mode line
 (column-number-mode 1)
 
-;; Bind major editing modes to certain file extensions 
+
+;;;; modes
+
+;; Bind major editing modes to certain file extensions
 (setq auto-mode-alist (cons '("\\.zcml$" . sgml-mode) auto-mode-alist))
 (setq auto-mode-alist (cons '("\\.pt$" . sgml-mode) auto-mode-alist))
 (setq auto-mode-alist (cons '("\\.cpt$" . sgml-mode) auto-mode-alist))
 (setq auto-mode-alist (cons '("\\.cpy$" . python-mode) auto-mode-alist))
 (setq auto-mode-alist (cons '("\\.vpy$" . python-mode) auto-mode-alist))
 
-;; Turn off the status bar and on the mouse if we're not in a window system
-(menu-bar-mode (if window-system 1 -1))
+;; set auto-fill for appropriate modes
 (add-hook 'text-mode-hook 'turn-on-auto-fill)
-
 (add-hook 'sgml-mode-hook 'turn-off-auto-fill)
 
+;; set the grep command....for some reason
 (setq grep-command "grep -liE")
 
-;; recentf stuff
+
+;;;; recent history stuff
 (require 'recentf)
 (recentf-mode 1)
 (setq recentf-max-menu-items 25)
 (global-set-key "\C-x\ \C-r" 'recentf-open-files)
 
-;; full-steam-ahead-and-damn-the-torpedoes
+;;;; full-steam-ahead-and-damn-the-torpedoes
 (defun
   full-steam-ahead-and-damn-the-torpedoes
   (prompt) t)
@@ -65,6 +107,8 @@
 (require 'uniquify)
 (setq uniquify-buffer-name-style 'post-forward)
 
+;;;;
+
 ;; wheel mouse
 (global-set-key [mouse-4] 'scroll-down)
 (global-set-key [mouse-5] 'scroll-up)
@@ -74,6 +118,8 @@
 
 (global-set-key "\M-g" 'goto-line)
 
+;;;; python
+
 ;; (when (load "flymake" t)
 ;;   (defun flymake-pyflakes-init ()
 ;;     (let* ((temp-file (flymake-init-create-temp-buffer-copy
@@ -82,16 +128,12 @@
 ;; 			temp-file
 ;; 			(file-name-directory buffer-file-name))))
 ;;       (list "pyflakes" (list local-file))))
-  
 ;;   (add-to-list 'flymake-allowed-file-name-masks
 ;; 	       '("\\.py\\'" flymake-pyflakes-init)))
 
 ;; (add-hook 'find-file-hook 'flymake-find-file-hook)
-(server-start)
 
 (fset 'break "import pdb; pdb.set_trace();\C-a\C-i")
 (add-hook 'python-mode-hook
           '(lambda ()
              (local-set-key  [(meta ?p) (meta ?p)] 'break)))
-
-(setq-default show-trailing-whitespace t)
--- a/.fluxbox/keys	Wed May 16 08:58:47 2012 -0700
+++ b/.fluxbox/keys	Wed Jun 19 10:58:18 2013 -0700
@@ -1,38 +1,30 @@
-! fluxbox-update_configs added '(workspace=[current])' to (Next|Prev)(Window|Group)
-! check lines marked by 'FBCV13' if they are correctly updated
-!mouse actions added by fluxbox-update_configs
 OnTitlebar Mouse1 :MacroCmd {Focus} {Raise} {ActivateTab}
-!mouse actions added by fluxbox-update_configs
+
 OnTitlebar Move1 :StartMoving
 OnLeftGrip Move1 :StartResizing bottomleft
 OnRightGrip Move1 :StartResizing bottomright
 OnWindowBorder Move1 :StartMoving
 
-!mouse actions added by fluxbox-update_configs
 OnTitlebar Mouse2 :StartTabbing
 
-!mouse actions added by fluxbox-update_configs
 OnTitlebar Double Mouse1 :Shade
 OnTitlebar Mouse3 :WindowMenu
 
-!mouse actions added by fluxbox-update_configs
 OnWindow Mod1 Mouse1 :MacroCmd {Raise} {Focus} {StartMoving}
 OnWindow Mod1 Mouse3 :MacroCmd {Raise} {Focus} {StartResizing BottomRight}
 
-!mouse actions added by fluxbox-update_configs
-OnToolbar Mouse4 :NextWorkspace
-OnToolbar Mouse5 :PrevWorkspace
-
-!mouse actions added by fluxbox-update_configs
+# desktop + mouse interaction
 OnDesktop Mouse1 :hideMenus
 OnDesktop Mouse2 :workspaceMenu
 OnDesktop Mouse3 :rootMenu
 OnDesktop Mouse4 :nextWorkspace
 OnDesktop Mouse5 :prevWorkspace
+OnToolbar Mouse4 :NextWorkspace
+OnToolbar Mouse5 :PrevWorkspace
 
-# File generated by FluxConf
-Mod1 Tab :nextwindow (workspace=[current]) !! FBCV13 !!
-Mod1 Shift Tab :prevwindow (workspace=[current]) !! FBCV13 !!
+# window navigation
+Mod1 Tab :NextWindow (workspace=[current]) (stuck=no)
+Mod1 Shift Tab :PrevWindow (workspace=[current]) (stuck=no)
 Control Mod1 Left :prevworkspace
 Control Mod1 Right :nextworkspace
 Mod1 F1 :Workspace 1
@@ -46,13 +38,26 @@
 Mod1 F9 :Workspace 9
 Mod1 F10 :Workspace 10
 
+# turn off caps lock
+# None 66 : someday!
+
+# window manipulation
 Shift Right :MaximizeHorizontal
 Shift Up :MaximizeVertical
 F11 :Fullscreen
 Menu :RootMenu
+Mod4 t :ToggleDecor
+
+# media keys
+# 107 = Print
+# 122 = XF86AudioLowerVolume
+# 123 = XF86AudioRaiseVolume
+None 107 :ExecCommand import -window root -silent /home/jhammel/screenshot.png
+None 122 :ExecCommand aumix -v-10
+None 123 :ExecCommand aumix -v+10
 
 # commands
-Control Mod1 a :ExecCommand xclip -o | python /home/jhammel/python/window_path.py | xclip -i
+Control Mod1 a :ExecCommand xclip -o | python /home/jhammel/python/window_path.py | xclip -i # absolute path of selected
 Control Mod1 b :ExecCommand sleep 1; xset dpms force off # blank screen
 Control Mod1 c :ExecCommand xterm -geometry 22x9 -T "`date +'%b %-d'`" -e 'cal; sleep 10' # calender
 Control Mod1 d :ExecCommand date | xclip -i # put now's date on the X clipboard
@@ -61,16 +66,32 @@
 Control Mod1 g :ExecCommand gkrellm
 Control Mod1 h :ExecCommand /home/jhammel/bin/keyshelp.sh # hotkeys help
 Control Mod1 i :ExecCommand import /home/jhammel/screenshot.png
-Control Mod1 k :ExecCommand echo $(curl $(xclip -o)?format=text) - $(xclip -o) | xclip -i # bitsyblog entry
+Control Mod1 k :ExecCommand emacs /home/jhammel/docs/projects/ims/journal.txt # ISM journal entry
 Control Mod1 l :ExecCommand echo http://letmegooglethatforyou.com/?q=$(xclip -o) | xclip -i
-Control Mod1 m :ExecCommand  xterm -e alsamixer # mixer
+Control Mod1 m :ExecCommand thunderbird # mail (thunderbird)
 Control Mod1 o :ExecCommand xclip -o | /home/jhammel/python/onelineit.py | xclip -i # put the clipboard contents on one line
-Control Mod1 p :ExecCommand xclip -o | /home/jhammel/python/pbmoz.py | xclip -i 
+Control Mod1 p :ExecCommand xclip -o | /home/jhammel/python/pbmoz.py | xclip -i # pastebin
+Control Mod1 q :ExecCommand xclip -o | /home/jhammel/python/quote.py | xclip -i # quote using >'s
 Control Mod1 r :ExecCommand import -window root -silent /home/jhammel/screenshot.png
-Control Mod1 q :ExecCommand xclip -o | sed 's/^/> /' | xclip -i # quote using >'s
 Control Mod1 s :ExecCommand /home/jhammel/bin/smartopen "$(xclip -o)" # smartopen
 Control Mod1 t :ExecCommand gnome-terminal # terminal
 Control Mod1 x :ExecCommand xkill
 Control Mod1 0 :ExecCommand xclip -o | sed 's/^[-+]//' | xclip -i # strip leading +s
+Control Shift / :ExecCommand /home/jhammel/bin/keyshelp.sh # hotkeys help
 
-Mod4 t :ToggleDecor
+# unused keys...what to do, what to do....
+# j: ?
+# r: if printscreen works
+# u: -> url open, freeing 's' for ???
+# v: ?
+# w: ?
+# y: ?
+# z: zoom?
+
+# TODO: screenshots
+# http://askubuntu.com/questions/168117/how-to-automatically-add-meta-tags-to-screenshot?rq=1
+
+# also, l could go to launch to free up s
+
+# the graveyard!
+# where old commands go to ...
--- a/.fluxbox/menu	Wed May 16 08:58:47 2012 -0700
+++ b/.fluxbox/menu	Wed Jun 19 10:58:18 2013 -0700
@@ -3,20 +3,20 @@
 [include] (~/.fluxbox/applications)
 
 [submenu] (fluxbox)
-[exec] (edit menu) { emacs ~/web/site/programs.html ~/.fluxbox/menu && ~/python/html2flux.py ~/web/site/programs.html > ~/.fluxbox/applications }
+[exec] (edit menu) { emacs ~/.fluxbox/menu ~/web/site/programs.html && ~/python/html2flux.py ~/web/site/programs.html > ~/.fluxbox/applications }
 [exec] (edit init) { emacs ~/.fluxbox/init }
 [exec] (edit keys) { emacs ~/.fluxbox/keys }
-[config] (Configure) 
+[config] (Configure)
 [submenu] (Styles)
  [stylesdir] (~/.fluxbox/styles)
 [end]
-[workspaces] (Workspace List) 
+[workspaces] (Workspace List)
 [restart] (gnome-session) {gnome-session}
-[commanddialog] (Fluxbox Command) 
-[reconfig] (Reload config) 
-[restart] (Restart) 
-[exec] (About) {(fluxbox -v; fluxbox -info | sed 1d) 2> /dev/null | xmessage -file - -center} 
-[separator] 
-[exit] (Exit) 
+[commanddialog] (Fluxbox Command)
+[reconfig] (Reconfig)
+[restart] (Restart)
+[exec] (About) {(fluxbox -v; fluxbox -info | sed 1d) 2> /dev/null | xmessage -file - -center}
+[separator]
+[exit] (Exit)
 [end]
 [end]
--- a/.fluxbox/startup	Wed May 16 08:58:47 2012 -0700
+++ b/.fluxbox/startup	Wed Jun 19 10:58:18 2013 -0700
@@ -1,5 +1,6 @@
 # fluxbox startup-script:
 
+PATH=~/firefox:$PATH
 /usr/bin/fbsetroot -solid black
 
 xrdb ~/.Xresources
--- a/.gitconfig	Wed May 16 08:58:47 2012 -0700
+++ b/.gitconfig	Wed Jun 19 10:58:18 2013 -0700
@@ -4,4 +4,10 @@
 	name = Jeff Hammel
 	email = jhammel@mozilla.com
 [alias]
-        st = status
\ No newline at end of file
+        branches = branch -a
+        branchname = git rev-parse --abbrev-ref HEAD
+        discard = reset HEAD --hard
+        patch = !git diff > ~/$(git rev-parse --abbrev-ref HEAD).diff
+        root = rev-parse --show-toplevel
+        st = status
+        up = !git pull mozilla master && git push origin master
--- a/.hgrc	Wed May 16 08:58:47 2012 -0700
+++ b/.hgrc	Wed Jun 19 10:58:18 2013 -0700
@@ -3,6 +3,7 @@
 ignore = /home/jhammel/.hgignore
 merge = meld
 verbose = True
+patch =
 
 [defaults]
 commit = -v
@@ -23,6 +24,7 @@
 rebase =
 convert =
 share =
+purge =
 
 [trusted]
 users = jhammel
--- a/.irssi/config	Wed May 16 08:58:47 2012 -0700
+++ b/.irssi/config	Wed Jun 19 10:58:18 2013 -0700
@@ -8,6 +8,11 @@
     address = "irc.mozilla.org";
     chatnet = "mozilla";
     autoconnect = "Yes";
+  },
+  {
+    address = "irc.w3.org";
+    chatnet = "w3c";
+    autoconnect = "Yes";
   }
 );
 
@@ -22,6 +27,7 @@
   };
   SILC = { type = "SILC"; };
   mozilla = { type = "IRC"; };
+  w3c = { type = "IRC"; };
 };
 
 channels = (
@@ -29,9 +35,12 @@
 
   { name = "#developers"; chatnet = "mozilla"; autojoin = "Yes"; },
   { name = "#ateam"; chatnet = "mozilla"; autojoin = "Yes"; },
-  { name = "#build"; chatnet = "mozilla"; autojoin = "Yes"; }
+  { name = "#releng"; chatnet = "mozilla"; autojoin = "Yes"; }
   { name = "#sf"; chatnet = "mozilla"; autojoin = "Yes"; }
   { name = "#jetpack"; chatnet = "mozilla"; autojoin = "Yes"; }
+  { name = "#build"; chatnet = "mozilla"; autojoin = "Yes"; }
+
+  { name = "#testing"; chatnet = "w3c"; autojoin = "Yes"; }
 );
 
 aliases = {
@@ -204,3 +213,12 @@
 };
 hilights = ( { text = "jhammel"; } );
 ignores = ( { mask = "JOINS"; level = "QUITS"; } );
+
+# How to save a window buffer [TODO: -> command]
+# http://forums.bsdnexus.com/viewtopic.php?id=1368
+#  all the output from the lastlog command will be saved to a file stored by default in your homedir.
+
+
+# /window log on
+# /lastlog -force
+# /window log off
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.mozutils	Wed Jun 19 10:58:18 2013 -0700
@@ -0,0 +1,2 @@
+mozilla_central: ~/mozilla/src/mozilla-try
+talos: ~/talos
\ No newline at end of file
--- a/.mutt/aliases	Wed May 16 08:58:47 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-alias design topp-design-discussion@lists.openplans.org
-alias dev opencore-dev@lists.openplans.org
-alias it xavier@openplans.org, ladorval@gmail.com, rmarianski@openplans.org
-alias ops operations-discussion@lists.openplans.org
-alias ra Rob Miller <robm@openplans.org>
-alias rm Rob Marianski <rmarianski@openplans.org>
-alias ui opencore-ui@lists.openplans.org
-alias wfh wfh@lists.openplans.org
\ No newline at end of file
--- a/.muttrc	Wed May 16 08:58:47 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-set allow_ansi		# allow ANSI color codes in messages.
-set attach_split	# handle every single attachment instead of concat
-set check_new		  # search for new messages in maildir/MH folders.
-set smtp_url="smtp://jhammel@mail.openplans.org"
-set spoolfile=imaps://mail.openplans.org/INBOX
-set folder=imaps://mail.openplans.org
-set editor="emacs -nw"
-set nomove
-set from="jhammel@openplans.org"
-set hostname="openplans.org"
-set timeout=5
-set mail_check=5
-set sort=reverse-threads
-set sort_aux=date-received
-set pager_stop
-set realname="Jeff Hammel"
-set record="imaps://mail.openplans.org/INBOX.Sent"
-set abort_unmodified=no
-set implicit_autoview
-set markers=no
-
-set use_from=yes
-set use_envelope_from=yes
-
-source ~/.mutt/aliases
-set alias_file=~/.mutt/aliases            # Keep aliases in this file.
-
-color normal default default
-
-macro index d "<delete-message><previous-undeleted>"
-macro pager d "<delete-message><previous-undeleted>"
-
-# Ignore all headers
-ignore *
-
-# Then un-ignore the ones I want to see
-unignore From:
-unignore To:
-unignore Reply-To:
-unignore Subject:
-unignore Date:
-unignore CC:
-unignore BCC:
-
-# Now order the visable header lines
-hdr_order From: Subject: To: CC: BCC: Reply-To: Date:
-
-bind pager < previous-line
-bind pager > next-line
\ No newline at end of file
--- a/.smartopen.ini	Wed May 16 08:58:47 2012 -0700
+++ b/.smartopen.ini	Wed Jun 19 10:58:18 2013 -0700
@@ -1,3 +1,3 @@
 [DEFAULTS]
-handlers = Bugzilla, GoogleMaps, Wikipedia, Wiktionary, FedEx, MercurialRevision, URL, Google
+handlers = Bugzilla, GoogleMaps, Wikipedia, Wiktionary, FedEx, MercurialRevision, URL, UbuntuPackage, Google
 
--- a/.subversion_config/config	Wed May 16 08:58:47 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,103 +0,0 @@
-### This file configures various client-side behaviors.
-###
-### The commented-out examples below are intended to demonstrate
-### how to use this file.
-
-### Section for authentication and authorization customizations.
-[auth]
-### Set store-passwords to 'no' to avoid storing passwords in the
-### auth/ area of your config directory.  It defaults to 'yes'.
-### Note that this option only prevents saving of *new* passwords;
-### it doesn't invalidate existing passwords.  (To do that, remove
-### the cache files by hand as described in the Subversion book.)
-# store-passwords = no
-### Set store-auth-creds to 'no' to avoid storing any subversion
-### credentials in the auth/ area of your config directory.
-### It defaults to 'yes'.  Note that this option only prevents
-### saving of *new* credentials;  it doesn't invalidate existing
-### caches.  (To do that, remove the cache files by hand.)
-# store-auth-creds = no
-
-### Section for configuring external helper applications.
-[helpers]
-### Set editor to the command used to invoke your text editor.
-###   This will override the environment variables that Subversion
-###   examines by default to find this information ($EDITOR, 
-###   et al).
-# editor-cmd = editor (vi, emacs, notepad, etc.)
-### Set diff-cmd to the absolute path of your 'diff' program.
-###   This will override the compile-time default, which is to use
-###   Subversion's internal diff implementation.
-# diff-cmd = diff_program (diff, gdiff, etc.)
-### Set diff3-cmd to the absolute path of your 'diff3' program.
-###   This will override the compile-time default, which is to use
-###   Subversion's internal diff3 implementation.
-# diff3-cmd = diff3_program (diff3, gdiff3, etc.)
-### Set diff3-has-program-arg to 'true' or 'yes' if your 'diff3'
-###   program accepts the '--diff-program' option.
-# diff3-has-program-arg = [true | false]
-
-### Section for configuring tunnel agents.
-[tunnels]
-### Configure svn protocol tunnel schemes here.  By default, only
-### the 'ssh' scheme is defined.  You can define other schemes to
-### be used with 'svn+scheme://hostname/path' URLs.  A scheme
-### definition is simply a command, optionally prefixed by an
-### environment variable name which can override the command if it
-### is defined.  The command (or environment variable) may contain
-### arguments, using standard shell quoting for arguments with
-### spaces.  The command will be invoked as:
-###   <command> <hostname> svnserve -t
-### (If the URL includes a username, then the hostname will be
-### passed to the tunnel agent as <user>@<hostname>.)  If the
-### built-in ssh scheme were not predefined, it could be defined
-### as:
-# ssh = $SVN_SSH ssh
-### If you wanted to define a new 'rsh' scheme, to be used with
-### 'svn+rsh:' URLs, you could do so as follows:
-# rsh = rsh
-### Or, if you wanted to specify a full path and arguments:
-# rsh = /path/to/rsh -l myusername
-### On Windows, if you are specifying a full path to a command,
-### use a forward slash (/) or a paired backslash (\\) as the
-### path separator.  A single backslash will be treated as an
-### escape for the following character.
-
-### Section for configuring miscelleneous Subversion options.
-[miscellany]
-### Set global-ignores to a set of whitespace-delimited globs
-### which Subversion will ignore in its 'status' output, and
-### while importing or adding files and directories.
-global-ignores = *.o *.lo *.la #*# .*.rej *.rej .*~ *~ .#* .DS_Store *.pyc *.egg-info
-### Set log-encoding to the default encoding for log messages
-# log-encoding = latin1
-### Set use-commit-times to make checkout/update/switch/revert
-### put last-committed timestamps on every file touched.
-# use-commit-times = yes
-### Set no-unlock to prevent 'svn commit' from automatically
-### releasing locks on files.
-# no-unlock = yes
-### Set enable-auto-props to 'yes' to enable automatic properties
-### for 'svn add' and 'svn import', it defaults to 'no'.
-### Automatic properties are defined in the section 'auto-props'.
-# enable-auto-props = yes
-
-### Section for configuring automatic properties.
-[auto-props]
-### The format of the entries is:
-###   file-name-pattern = propname[=value][;propname[=value]...]
-### The file-name-pattern can contain wildcards (such as '*' and
-### '?').  All entries which match will be applied to the file.
-### Note that auto-props functionality must be enabled, which
-### is typically done by setting the 'enable-auto-props' option.
-# *.c = svn:eol-style=native
-# *.cpp = svn:eol-style=native
-# *.h = svn:eol-style=native
-# *.dsp = svn:eol-style=CRLF
-# *.dsw = svn:eol-style=CRLF
-# *.sh = svn:eol-style=native;svn:executable
-# *.txt = svn:eol-style=native
-# *.png = svn:mime-type=image/png
-# *.jpg = svn:mime-type=image/jpeg
-# Makefile = svn:eol-style=native
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/apply.sh	Wed Jun 19 10:58:18 2013 -0700
@@ -0,0 +1,9 @@
+#!/bin/bash
+# apply a patch from the web
+# TODO: take from file as well
+
+LVL=1
+if ((curl $1 2> /dev/null) | (patch -p${LVL} --dry-run -b > /dev/null))
+then
+  echo "hi"
+fi
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/clone-mozbase.sh	Wed Jun 19 10:58:18 2013 -0700
@@ -0,0 +1,5 @@
+#!/bin/bash
+
+git clone git@github.com:k0s/mozbase.git
+cd mozbase
+git remote add mozilla git@github.com:mozilla/mozbase.git
--- a/bin/desvn.sh	Wed May 16 08:58:47 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,24 +0,0 @@
-#!/bin/bash
-
-desvn() {
-    
-    if [ "$#" == "1" ]
-    then
-        cd $1
-    fi
-
-    svn ls | grep '.*/$' | while read line
-    do
-        desvn $line
-    done
-    rm -rf .svn
-
-    if [ "$#" == "1" ]
-    then
-        cd ..
-    fi
-
-
-}
-
-desvn
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/example/README.txt	Wed Jun 19 10:58:18 2013 -0700
@@ -0,0 +1,1 @@
+Example scripts of how to do particular things in bash
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/example/script-path.sh	Wed Jun 19 10:58:18 2013 -0700
@@ -0,0 +1,7 @@
+#!/bin/bash
+
+# echoes path to this script (example)
+
+echo "argv[0]: $0"
+path=`readlink -f $0`
+echo "path: ${path}"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/example/self-writing.sh	Wed Jun 19 10:58:18 2013 -0700
@@ -0,0 +1,33 @@
+#!/bin/bash
+
+# illustrate self-writing script (example)
+# This one does something hard and replaces dynamic data with sed.
+# Other solutions (magic markers, etc) are possible
+
+path=`readlink -f $0`
+mode=`stat --format '%a' ${path}`
+tmp=`tempfile --mode ${mode}`
+datestamp=`date`
+nonce="This script last generated at "
+
+# sanity check
+if [[ ! -w "${path}" ]]
+then
+    echo "You don't have write permission for script ${path}"
+    exit 1
+fi
+
+# avoiding -i for safety
+sed 's/\(echo \"'"${nonce}"'\).*\"/\1'"${datestamp}"'\"/' ${path} > ${tmp}
+if [[ ! -e "${tmp}" ]]
+then
+    echo "Temporary file creation not successful"
+    exit 1
+fi
+
+# echo last and current generation times for example
+echo "This script last generated at Sat Jun  8 08:52:35 PDT 2013"
+echo "Now: ${datestamp}"
+
+# move tmpfile -> script location via exec
+exec mv ${tmp} ${path}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/hg-merge-branch.sh	Wed Jun 19 10:58:18 2013 -0700
@@ -0,0 +1,26 @@
+#!/bin/bash
+
+# merge a hg branch repo
+# from https://wiki.mozilla.org/User:Asasaki:Cedar
+# TODO: inclusion in mercurial utilities package
+
+if [[ "$#" != "3" ]]
+then
+    echo "Usage: hg-merge-branch.sh scheme://hg/repository"
+    exit 1
+fi
+
+if ! hg root
+then
+    exit 255
+fi
+
+# Update to latest
+# the hg up -C will blow away any local changes!
+#hg pull
+#hg up -C -r default
+
+# Pull latest branch changes in
+#hg pull $1
+#hg merge
+#hg commit -m "Merge m-c -> cedar"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/joke.sh	Wed Jun 19 10:58:18 2013 -0700
@@ -0,0 +1,13 @@
+#!/bin/bash
+
+title=$1
+shift
+
+if [[ "${title}" == ""  || "$#" == "0" ]]
+then
+    exit 1
+fi
+
+filename=~/web/site/comedy/cheapshots/${title}.txt
+
+echo "$@" > ${filename}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/xmoveall.sh	Wed Jun 19 10:58:18 2013 -0700
@@ -0,0 +1,37 @@
+#!/bin/bash
+
+# move all windows to a desktop
+# by default, the final one (graveyard)
+
+# List  all  desktops  managed  by the window manager. One line is
+# output for each desktop, with the line broken up into space sep‐
+# arated  columns.  The  first  column contains an integer desktop
+# number. The second column contains a '*' character for the  cur‐
+# rent  desktop,  otherwise  it contains a '-' character. The next
+# two columns contain the fixed string DG: and  then  the  desktop
+# geometry as '<width>x<height>' (e.g. '1280x1024'). The following
+# two columns contain the fixed string VP: and then  the  viewport
+# position  in  the  format '<y>,<y>' (e.g. '0,0'). The next three
+# columns after this contains the fixed string WA:  and  then  two
+# columns  with  the workarea geometry as 'X,Y and WxH' (e.g. '0,0
+# 1280x998'). The rest of the line contains the name of the  desktop
+# (possibly containing multiple spaces).
+DESKTOP=$(wmctrl -d | awk '{if ($2 == "*") {print $1}}')
+
+# find the last desktop
+if (( $# ))
+then
+LAST=$1
+else
+LAST=$(wmctrl -d | tail -n 1 | awk '{print $1}')
+fi
+
+#  -l     List the windows being managed by the window manager.
+wmctrl -l | awk '{if ($2 == "'${DESKTOP}'") {print $1}}' | while read line
+do
+# -t <DESK>
+# Move  a window that has been specified with the -r action to the
+# desktop <DESK>.
+wmctrl -i -r ${line} -t ${LAST}
+done
+
--- a/python/accentuate.py	Wed May 16 08:58:47 2012 -0700
+++ b/python/accentuate.py	Wed Jun 19 10:58:18 2013 -0700
@@ -23,7 +23,7 @@
            'r': ['ᣨ', 'ჩ', 'я', 'Ɍ', 'ȓ', 'Ȓ', 'ȑ', 'Ȑ'],
            's': ['∫', '§', 'ᛊ', 'Ꮥ', 'క', 'ˢ', 'ȿ', 'ș', 'ᶘ'],
            't': ['Ṱ', 'ל', 'ᛠ', 'ᚁ', 'ፕ', 'Է', 'Ե', 'Ҭ', 'Ϯ', 'ʈ', 'Ⱦ', 'ȶ'],
-           'u': ['ṹ', 'ᥩ', 'ᥳ', 'ப', 'ն', 'Մ', 'μ', 'ǚ',],
+           'u': ['ṹ', 'ᥩ', 'ᥳ', 'ப', 'ն', 'Մ', 'μ', 'ǚ', 'μ'],
            'v': ['Ѵ', 'ᜥ', 'Ꮴ', 'Ѷ', 'ν', 'ΰ'],
            'w': ['Ѡ', 'Щ', 'ש', 'ឃ', 'ᜦ', 'Ꮤ', 'Ꮿ', 'ϣ'],
            'x': ['χ', 'Ӽ', 'ӽ', 'Ҳ', 'ҳ', 'Ϫ', 'ˣ'],
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/actions.py	Wed Jun 19 10:58:18 2013 -0700
@@ -0,0 +1,29 @@
+#!/usr/bin/env python
+
+class Actions(object):
+
+    def __init__(self):
+        self.functions = {}
+
+    def __call__(self, function, dependencies):
+        import pdb; pdb.set_trace()
+        self.functions[function.func_name] = function
+        return function
+
+    def do(self, func_name):
+        self.functions[func_name]()
+
+action = Actions()
+
+@action
+def foo():
+    print "hello"
+
+@action('foo')
+def bar():
+    print "goodbye"
+
+if __name__ == '__main__':
+    pass
+
+action.do('bar')
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/bind.py	Wed Jun 19 10:58:18 2013 -0700
@@ -0,0 +1,28 @@
+#!/usr/bin/env python
+
+"""
+illlustrate e.g. method bind for python
+"""
+
+class Foo(object):
+
+    @classmethod
+    def create(cls):
+        """create an instance and bind a method onto foo"""
+        class decorator(object):
+            def __init__(self, function):
+                self.function = function
+            def __call__(self):
+                print "Bar!"
+                return self.function()
+
+        instance = cls()
+        instance.foo = decorator(instance.foo)
+        return instance
+
+    def foo(self):
+        print "Foo!"
+
+if __name__ == '__main__':
+    foo = Foo.create()
+    foo.foo()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/dependencies.py	Wed Jun 19 10:58:18 2013 -0700
@@ -0,0 +1,40 @@
+#!/usr/bin/env python
+
+"""
+illustrate overriding ``setuptools.setup`` to read package data
+"""
+
+import imp
+import os
+import pprint
+import sys
+
+current_module = None
+info = {}
+
+def setup(**kwargs):
+    assert current_module
+    info[current_module] = kwargs
+
+def main(args=sys.argv[1:]):
+
+    global current_module
+    current_module = None
+
+    setuptools = sys.modules.get('setuptools')
+    sys.modules['setuptools'] = sys.modules[__name__]
+
+    try:
+        for setup_py in args:
+            current_module = setup_py
+            assert os.path.exists(setup_py)
+            module = imp.load_source('setup', setup_py)
+    finally:
+        sys.modules.pop('setuptools')
+        if setuptools:
+            sys.modules['setuptools'] = setuptoools
+
+    pprint.pprint(info)
+
+if __name__ == '__main__':
+    main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/dmenu.py	Wed Jun 19 10:58:18 2013 -0700
@@ -0,0 +1,53 @@
+#!/usr/bin/env python
+
+import optparse
+import os
+import shlex
+import subprocess
+import sys
+
+def choose_file(directory, dmenu='dmenu',
+                args=('-i', '-nb', 'black', '-nf', 'white',
+                      '-fn', '-*-lucidatypewriter-medium-r-*-*-*-120-*-*-*-*-*-*')):
+    """choose a file in the directory with dmenu"""
+    directory = os.path.abspath(directory)
+    files = os.listdir(directory)
+    string = '\n'.join(files)
+
+    if isinstance(dmenu, basestring):
+        dmenu = [dmenu]
+    dmenu = list(dmenu)
+    dmenu.extend(args)
+
+    process = subprocess.Popen(dmenu, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
+    stdout, _ = process.communicate(input=string)
+    if process.returncode:
+        return
+    chosen = os.path.join(directory, stdout)
+    if os.path.isdir(chosen):
+        return choose_file(chosen)
+    return chosen
+
+def main(args=sys.argv[1:]):
+    parser = optparse.OptionParser()
+    parser.add_option('-d', '--directory', dest='directory',
+                      default=os.getcwd(),
+                      help="call on this directory [Default: current directory]")
+    parser.add_option('-e', '--exec', dest='executable',
+                      help="call this proram with the result")
+    options, args = parser.parse_args(args)
+    chosen =  choose_file(options.directory)
+    if chosen:
+        if options.executable:
+            # TODO: extract this pattern (see ims journal.txt)
+            command = shlex.split(options.executable)
+            executable = command[0]
+            command.append(chosen)
+            os.execlp(executable, *command)
+        else:
+            print chosen
+    else:
+        sys.exit(1)
+
+if __name__ == '__main__':
+    main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/hg-tricks.py	Wed Jun 19 10:58:18 2013 -0700
@@ -0,0 +1,9 @@
+# check status
+/       # check for outstanding changes
+        output = self._call(['st']).strip()
+        lines = [line for line in output.splitlines()
+                 if not line.startswith('?')]
+        if lines:
+            print "Outstanding changes:"
+            print output
+            raise AssertionError
--- a/python/html2flux.py	Wed May 16 08:58:47 2012 -0700
+++ b/python/html2flux.py	Wed Jun 19 10:58:18 2013 -0700
@@ -1,30 +1,100 @@
 #!/usr/bin/env python
 
+"""
+transform an HTML <dl> file into a fluxbox menu
+if no file give, read from stdin
+
+<dl><a>submenu name</a>
+  <dt>program label</dt><dd>command</dd>
+  <dt>another program label</dt><dd>command2</dd>
+</dl>
+
+x-form -> internal format:
+
+('submenu name': [('program label', 'command'),
+                  ('another program label', 'command2')])
+"""
+
+import optparse
+import os
 import sys
 from lxml import etree
+from lsex import lsex # local import
 
-from lsex import lsex # local import
+# available executables
 executables = set([i.rsplit('/', 1)[-1] for i in lsex() ])
 
-def printmenu(dl, output, top=True):
-    
-    # XXX should do more checking
+def readmenu(dl, output, top=True):
+    """read menu from an <dl> tag"""
+    # TODO: probably don't really need lxml
+
+    menu_items = []
+    name = None # menu name
+    firstchild = True
+    label = None
     for child in dl.iterchildren():
-        if not top and child.tag == 'a':
-            print >> output, '[submenu] (%s)' % child.text
+
+        if not top and child.tag == 'a' and firstchild:
+            # TODO: better way of labeling this!
+            name = child.text.strip()
+
         if child.tag == 'dt':
-            label = ' '.join([ i.strip() for i in child.itertext() if i.strip() ])
+            # item label
+            label = ' '.join([i.strip() for i in child.itertext() if i.strip()])
         if child.tag == 'dd':
-            command = ' '.join([ i.strip() for i in child.itertext() if i.strip() ])
+            # command
+            command = ' '.join([i.strip() for i in child.itertext() if i.strip()])
+            # TODO: classes
             executable = command.split()[0]
-            if executable in executables:
-                print >> output, '[exec] (%s) {%s}' % (label, command)
+            if executable in executables or os.path.isabs(executable):
+                menu_items.append((label, command))
+
+        # submenu
         if child.tag == 'dl':
-            printmenu(child, output, top=False)
+            menu_items.append(readmenu(child, output, top=False))
+
+    return (name, menu_items)
+
+def printflux(name, menu, output, top=True):
+    """
+    - output: file-like object for writing
+    """
+
+    # print [submenu] tag for this menu
+    name = name or ''
+    if not top:
+        print >> output, '[submenu] (%s)' % name
+
+    # print menu items
+    for name, item in menu:
+        if isinstance(item, basestring):
+            # command
+            print >> output, '[exec] (%s) {%s}' % (name, item)
+        else:
+            # submenu
+            printflux(name, item, output, top=False)
+
+    # print end of this submenu
     if not top:
         print >> output, '[end]'
 
-def main(args = sys.argv[1:]):
+def printmenu(dl, output):
+    name, menu = readmenu(dl, output)
+    printflux(name, menu, output)
+
+def main(args=sys.argv[1:]):
+    """command line interface"""
+
+    # parse command line option
+    usage = '%prog [options] [menu.html]'
+    parser = optparse.OptionParser(usage=usage,
+                                   description=__doc__)
+    parser.add_option('--collapse', dest='collapse',
+                      action='store_true', default=False,
+                      help="collapse menus with a single item to that item")
+    parser.add_option('-o', '--output', dest='output',
+                      help="output file [Default: <stdout>]")
+    options, args = parser.parse_args(args)
 
     # setup input, output
     if args:
@@ -38,6 +108,7 @@
     dom = etree.fromstring(html)
     dl = dom.find('.//dl')
 
+    # print to stdout
     printmenu(dl, fluxout)
 
 if __name__ == '__main__':
--- a/python/install_config.py	Wed May 16 08:58:47 2012 -0700
+++ b/python/install_config.py	Wed Jun 19 10:58:18 2013 -0700
@@ -1,4 +1,5 @@
 #!/usr/bin/env python
+
 """
 installs config to a user's home directory
 this can be done with
@@ -17,15 +18,10 @@
 os.chdir(HOME)
 
 commands = [ # make the home directory a repository
-             ['hg', 'init'],
-             ['hg', 'pull', SRC],
-             ['hg', 'update', '-C'],
-
-             # site-specific files
-             ['mkdir', '-p', '.subversion'],
-             ['rm', '-f', '.subversion/config'],
-             ['ln', '-s', os.path.join(HOME, '.subversion_config/config'), os.path.join(HOME, '.subversion/config')],
-             ]
+    ['hg', 'init'],
+    ['hg', 'pull', SRC],
+    ['hg', 'update', '-C'],
+    ]
 
 def execute(*commands):
     """execute a series of commands"""
@@ -37,6 +33,7 @@
 
 execute(*commands)
 
+
 # get the which command
 sys.path.append(os.path.join(HOME, 'python'))
 from which import which
@@ -84,8 +81,10 @@
                              ['ln', '-s', os.path.join(HOME, 'silvermirror', 'bin', 'silvermirror'), os.path.join(HOME, 'bin', 'silvermirror') ],
                              ]
     execute(*postinstall_commands)
+else:
+    print "git not installed"
 
 # - ubuntu packages to install:
-PACKAGES="mercurial unison fluxbox antiword xclip graphviz python-dev python-lxml curl arandr"
+PACKAGES="mercurial unison fluxbox antiword xclip graphviz python-dev python-lxml curl arandr git emacs irssi"
 print "Ensure the following packages are installed:"
 print "sudo apt-get install %s" % PACKAGES
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/prime.py	Wed Jun 19 10:58:18 2013 -0700
@@ -0,0 +1,19 @@
+#!/usr/bin/env python
+
+def prime(number):
+    half = int(number / 2)
+    for i in range(2, half):
+        if not number % i:
+            return False
+    return True
+
+def primes(n):
+    return [i for i in range(2,n)
+            if not [True for j in range(2,1 + i/2)
+                    if not i%j]]
+
+
+if __name__ == '__main__':
+    import sys
+    for arg in sys.argv[1:]:
+        print prime(int(arg))
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/quote.py	Wed Jun 19 10:58:18 2013 -0700
@@ -0,0 +1,31 @@
+#!/usr/bin/env python
+
+"""
+quote text
+"""
+
+import sys
+import textwrap
+from subprocess import check_output as call
+
+def quote(text, prefix='> ', width=69):
+    """
+    returns quoted text
+    - prefix: string to prepend quote
+    - width: final width (emacs wraps at 70)
+    """
+    width -= len(prefix) # subtract the prefix
+    text = text.strip() # remove surrounding whitespace
+    lines = []
+    for line in text.splitlines():
+        line = line.strip()
+        lines.extend(textwrap.wrap(line, width))
+    return '\n'.join(['%s%s' % (prefix, line)
+                      for line in lines])
+
+def main(args=sys.argv[1:]):
+    text = sys.stdin.read()
+    sys.stdout.write(quote(text))
+
+if __name__ == '__main__':
+    main()
--- a/python/randomize.py	Wed May 16 08:58:47 2012 -0700
+++ b/python/randomize.py	Wed Jun 19 10:58:18 2013 -0700
@@ -7,11 +7,16 @@
 
 from optparse import OptionParser
 
+"""randomize a bunch of files"""
+
 if __name__ == '__main__':
-    parser = OptionParser()
+    usage = '%prog [options] file_or_directory <...>'
+    parser = OptionParser(usage=usage, description=__doc__)
     parser.add_option("-e", "--exec", dest="callable",
-                      help="program to execute")
-    (options, argv) = parser.parse_args()
+                      help="program to execute for each file")
+    options, argv = parser.parse_args()
+    if not argv:
+        argv = ['.']
     args = []
     for i in argv:
         if os.path.isdir(i):
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/recipes.txt	Wed Jun 19 10:58:18 2013 -0700
@@ -0,0 +1,3 @@
+Catalog of Generic Requested Python Implementations That Should Be Written
+
+(empty placeholder)
--- a/python/require.py	Wed May 16 08:58:47 2012 -0700
+++ b/python/require.py	Wed Jun 19 10:58:18 2013 -0700
@@ -9,7 +9,7 @@
     import urllib2
     contents = urllib2.urlopen(url).read()
     filename = url.rsplit('/', 1)[-1]
-    module = filename.rsplit('.', 1)[-1]
+    module = filename.rsplit('.', 1)[0]
     dest = tempfile.mkstemp(suffix='.py', prefix=module)
     f = file(dest, 'w')
     f.write(contents)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/resource_filename.py	Wed Jun 19 10:58:18 2013 -0700
@@ -0,0 +1,21 @@
+#!/usr/bin/env python
+
+# example code
+
+import os
+
+def resource_path(path):
+    """
+    getting a resource filename (absolute path)
+    - path: relative path
+    """
+
+    try:
+        # use pkg_resources if available
+        # http://pythonhosted.org/distribute/setuptools.html#non-package-data-files
+        from pkg_resources import Requirement, resource_filename
+        return resource_filename(Requirement.parse("MyProject"),path)
+    except ImportError:
+        # assume file lives relative to this file
+        here = os.path.dirname(os.path.abspath(__file__))
+        return os.path.join(here, path)
--- a/python/setup_repo.py	Wed May 16 08:58:47 2012 -0700
+++ b/python/setup_repo.py	Wed Jun 19 10:58:18 2013 -0700
@@ -1,11 +1,23 @@
 #!/usr/bin/env python
 
+"""
+setup a repository
+
+Parameters:
+- host URL
+- location on host disk
+"""
+
 import os
 import subprocess
 import sys
+import urlparse
 
+from subprocess import check_call as call
 from optparse import OptionParser
 
+
+# global variables
 HOST='k0s.org'
 HGRC="""[paths]
 default = http://%(host)s/%(repo)s/%(name)s
@@ -13,39 +25,58 @@
 """
 
 def call(command, *args, **kw):
-  code = subprocess.call(command, *args, **kw)
-  if isinstance(command, basestring):
-    cmdstr = command
-  else:
-    cmdstr = ' '.join(command)
-  print cmdstr
-  if code:
-    raise SystemExit("Command `%s` exited with code %d" % (cmdstr, code))
-        
+
+    code = subprocess.call(command, *args, **kw)
+    if isinstance(command, basestring):
+        cmdstr = command
+    else:
+        cmdstr = ' '.join(command)
+    print cmdstr
+    if code:
+        raise SystemExit("Command `%s` exited with code %d" % (cmdstr, code))
+
 def main(args=sys.argv[1:]):
 
-  parser = OptionParser('%prog [options] location')
-  parser.add_option('-m', '--message',
-                    help='commit message')
-  options, args = parser.parse_args(args)
-  
-  if len(args) != 1:
-    parser.print_usage()
-    parser.exit()
+    # parse command line arguments
+    parser = OptionParser('%prog [options] location')
+    parser.add_option('-m', '--message', dest='message',
+                      help='commit message')
+    parser.add_option('-u', '--remote-url', dest='remote_url',
+                      default="http://k0s.org/hg/",
+                      help="URL of host hg repository collection [Default: %default]")
+    parser.add_options('-p', '--remote-path', dest='remote_path',
+                       help="remote path of hg repository links; otherwise taken from --remote-url, if specified")
+    options, args = parser.parse_args(args)
+    if len(args) != 1:
+        parser.print_usage()
+        parser.exit()
+    # TODO: sanity check for remote_url, remote_path
 
-  repo = args[0].strip('/')
-  
-  directory = os.getcwd()
-  name = os.path.basename(directory)
-  os.chdir('..')
-  call(['scp', '-r', name, '%s:~/%s/' % (HOST, repo)])
-  call(['ssh', HOST, "cd %s/%s && hg init && hg add && hg ci -m '%s'" % (repo, name, options.message or 'initial commit of %s' % name)])
-  os.chdir(directory)
-  call(['hg', 'init'])
-  call(['hg', 'pull', 'http://%s/%s/%s' % (HOST, repo, name)])
-  call(['hg', 'update', '-C'])
-  f = file(os.path.join('.hg', 'hgrc'), 'a')
-  print >> f, HGRC % { 'host': HOST, 'repo': repo, 'name': name}
+    # setup repository
+    name = os.path.basename(directory)
+    call(['hg', 'init'])
+    call(['hg', 'add'])
+    call(['hg', 'commit', '-m', options.message or 'initial commit of %s' %name])
+
+    # setup remote, if specified
+    if options.remote_url:
+
+        # parse remote URL
+        host, netloc, path, query, anchor = urlparse.urlsplit(options.remote_url)
+        if options.remote_path:
+            remote_host = host
+            if ':' in remote_path:
+                remote_host, remote_path = remote_path.split(':', 1)
+        else:
+            remote_path = path
+
+        # setup remote repository
+        call(['ssh', HOST, "cd %s/%s && hg init && hg add && hg ci -m '%s'" % (repo, name, options.message or 'initial commit of %s' % name)])
+
+        # write local .hgrc file
+        # TODO: use ConfigParser
+        f = file(os.path.join('.hg', 'hgrc'), 'w')
+        print >> f, HGRC % { 'host': HOST, 'repo': repo, 'name': name}
 
 if __name__ == '__main__':
   main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/tmpbuffer.py	Wed Jun 19 10:58:18 2013 -0700
@@ -0,0 +1,28 @@
+#!/usr/bin/env python
+
+# from http://k0s.org/hg/bitsyblog/file/5c04cf601aba/bitsyblog/blogme.py
+
+import os
+import subprocess
+import tempfile
+
+def tmpbuffer(editor=None):
+    """open an editor and retreive the resulting editted buffer"""
+
+    if not editor:
+        editor = os.environ.get('EDITOR')
+        if not editor:
+            raise Exception("tmpbuffer: editor not supplied and EDITOR not defined")
+    tmpfile = tempfile.mktemp(suffix='.txt')
+    cmdline = editor.split() # XXX shlex would be more powerful
+    cmdline.append(tmpfile)
+    edit = subprocess.call(cmdline)
+    buffer = file(tmpfile).read().strip()
+    os.remove(tmpfile)
+    return buffer
+
+if __name__ == '__main__':
+    # purely for testing/illustration purposes
+    contents = tmpbuffer()
+    print contents
+