bash completion for unison

just add the following to you ~/.bashrc or to /etc/bash_completion.d/unison:
_unison() { COMPREPLY=( $(compgen -W "$(find ~/.unison -name '*.prf' -printf '%P ')" -- "${COMP_WORDS[COMP_CWORD]}" ) ); }
complete -F _unison unison
http://www.cis.upenn.edu/~bcpierce/unison/

C# Conditional Execution

[ConditionalAttribute("DEBUG")] for methods. All calls to that method are only executed in Debug builds!

man wrapper: man in own window

Alt-F2, man emacs.

well, this does not work. not automatically.

i created a wrapper-script in ~/bin (which is first in my path variable) with the following content:

#!/bin/bash
# mru, jun 2010

# if ! [ -t 0 ]; then
if [ "$DISPLAY" ]; then
 exec gnome-terminal --hide-menubar --title "man $@" -x /usr/bin/man "$@"
else 
 exec /usr/bin/man "$@"
fi

to make it work.

one could use if ! [ -t 0 ]; then to get a normal in-terminal man if in terminal and a seperate gnome-terminal if in X11.

latexmk super powers

latexmk is a handy tool to build latex documents. these days i investigated in the advanced usage of latexmk.

latexmk can use configuration files, latexmkrc in the current directory is used as a default, then ~/.latexmkrc.

with latexmk -pvc latexmk watches a .tex file and builds it whenever its content or a dependency of it changes. -pvc also opens a viewer for the file and updates it, so it really supports the workflow when editing latex documents.

a sample latexmkrc file might look like that:

$pdf_previewer = 'start evince';
@default_files = ('thesis');
$print_type = 'pdf';
$pdf_mode = 1;
$pdflatex = 'pdflatex -interaction=nonstopmode -halt-on-error';

update: $pdflatex = 'pdflatex -interaction=nonstopmode -halt-on-error'; makes pdflatex stop on the first error, not asking for any user input.

watch-files

just like continuous-make, but executes arbitrary commands when a file changes.

#! /bin/bash

# mru, feb 2010
# if a file changes, execute command

# example:
#
# watch-file document.tex lit.bib latexmk

# 

function error() {
 echo "error: $@"
 echo "${0##*/} {files-to-watch} 'command-upon-modification'"
 exit 1
}

if [ ${#} -lt 2 ]; then
 error "not enough arguments"
fi


while [ $# -gt 1 ]; do
 FILES=(${FILES[*]} "$1")
 shift
done

CMD=$*

for i in "${FILES[@]}"; do
 if [ -z "$i" ] || ! [ -f "$i" ]; then
  error "no such file: $i"
 fi
done

echo "${0##*/}: onchange ("
for i in "${FILES[@]}"; do
 echo " * $i"
done
echo ") { ${CMD} }"

ftime() { stat -c %y "${FILES[@]}"; }

D=$(ftime)
while true; do
 sleep 1
 DN=$(ftime)
 if [ "$D" != "$DN" ]; then
  $CMD
  D="$DN"
 fi
done

continuous make

build-on-save is easy. i put this in my .bash_aliases and use it everywhere!

continuous-make() {
 while true; do
  if ! make "$@" -q; then
   make "$@"
  fi
  sleep 1
 done
}

you can use it like that:

continuous-make doc

and it will call make doc whenever a dependency of doc is changed.

mydoc: documentation management

i have a lot of pdf files lying around. some of these files are datasheets, some manuals. i repeatedly access them, and because usually i can't find them fast enough, i search the internet and download it the thousandth time. but not any longer! mydoc behaves like texdoc, but for my own documents.

it accepts arguments that are used as conjuncted filters.

if more files match the filters, a selection dialog is displayed

it detects if its called from console or from gui (Alt-F2, e.g.).

#! /bin/bash

# search $MYDOCPATH for pdf documents
# commandline arguments are used as conjucted -iname's
#
# mru, may 2010


# configure where to search for the pdf's
MYDOCPATH=~/dev/01atmel/terrarium/docs/:~/dev/01atmel/stepper/docs/:~/books/




set -f  # no globbing, free the star!


# detect if run in console
# the variable TERM is used to automagically call the right function
if [ -t 0 ]; then
 TERM='cli'
else
 TERM='x11'
fi

error_cli() { echo "$*"; }
error_x11() { zenity --warning --text "$*" --title "${0##*/}"; }
info_cli()  { echo "$*"; }
info_x11()  { zenity --info --text "$*"  --title "${0##*/}"; }

usage()     { info_$TERM "usage: ${0##*/} {filter-string}"; } 
open()      { gnome-open "$@"; }

get_choice_cli() {
 PS3=$'more possible matches; select the file to open or change filter: '
 select c in $@ ; do  
  echo $c
  break
 done
}

get_choice_x11() {
 zenity --list \
  --width=800 \
  --height=450 \
  --text "select file" \
  --title "${0##*/}: filter not unique" \
  --column "filename" \
  "$@"
}

if [ -z "$MYDOCPATH" ]; then
 error_$TERM "\$MYDOCPATH not set"
 exit 1
fi


# create the `find` query, search for --help
while (( $# > 0 )); do
 if [ "$1" = "--help" ]; then
  usage
  exit 1
 fi

 QUERY="$QUERY -iwholename *$1*"
 shift
done


# call `find` for all paths in $MYDOCPATH and store the result in
# RESULTS

RESULTS=$(IFS=$': '; for i in $MYDOCPATH; do
 find $i -iname "*pdf" $QUERY
done)

# well, nothing found, RESULTS is empty
if [ -z "$RESULTS" ]; then
 info_$TERM "nothing found; stopping"
 exit 1
fi

# on unique match, open pdf
if (( $(wc -l <<< "$RESULTS") == 1 )); then
 open "$RESULTS"

# multiple matches, open selection
else
 IFS=$'\n'
 c=$(get_choice_$TERM $RESULTS)
 [ "$c" ] && open "$c"
fi