1#!/usr/local/bin/bash
2# A "tagged cd" implementation
3# Based on an idea by C. Scott Ananian (http://wiki.laptop.org/go/Experiments_with_unordered_paths)
4# Run this script with ". /path/to/pinot-cd.sh"
5
6MISSING_PROGRAM=1
7MISSING_INDEX=1
8MATCHES_COUNT=0
9
10# Check programs we need are available
11checkprograms()
12{
13  WHICH_BN=`which basename 2>/dev/null`
14  if [ $? != 0 ]; then
15    echo "Couldn't find basename. Is the coreutils package installed ?"
16    return
17  fi
18  WHICH_CAT=`which cat 2>/dev/null`
19  if [ $? != 0 ]; then
20    echo "Couldn't find cat. Is the coreutils package installed ?"
21    return
22  fi
23  WHICH_MKTEMP=`which mktemp 2>/dev/null`
24  if [ $? != 0 ]; then
25    echo "Couldn't find mktemp. Is the coreutils package installed ?"
26    return
27  fi
28  WHICH_GREP=`which grep 2>/dev/null`
29  if [ $? != 0 ]; then
30    echo "Couldn't find grep. Is the grep package installed ?"
31    return
32  fi
33  WHICH_SED=`which sed 2>/dev/null`
34  if [ $? != 0 ]; then
35    echo "Couldn't find sed. Is the sed package installed ?"
36    return
37  fi
38  WHICH_PS=`which pinot-search 2>/dev/null`
39  if [ $? != 0 ]; then
40    echo "Couldn't find pinot-search. Is the pinot package installed ?"
41    return
42  fi
43
44  MISSING_PROGRAM=0
45}
46
47# Check the daemon's index exists
48checkindex()
49{
50  if [ ! -d "$HOME/.pinot/daemon" ]; then
51    echo "Configure Pinot to crawl and index directories first."
52    return
53  fi
54
55  MISSING_INDEX=0
56}
57
58# Run the actual search and get matches
59runsearch()
60{
61  local TEMP_FILE=`mktemp`
62
63  pinot-search -l xapian "$HOME/.pinot/daemon" "type:x-directory/normal $1" 2>/dev/null | grep "file://" | sed -e "s/file:\/\/\(.*\)/\1/g" >$TEMP_FILE 2>/dev/null
64
65  local RESULTS=`cat $TEMP_FILE`
66  MATCHES_COUNT=`cat $TEMP_FILE|wc -l`
67
68  if [ $MATCHES_COUNT -eq 1 ]; then
69    echo $RESULTS
70    cd "$RESULTS"
71  elif [ $MATCHES_COUNT -gt 1 ] && [ $2 -eq 1 ]; then
72    echo "Matches for \"$1\":"
73    cat $TEMP_FILE
74  elif [ $MATCHES_COUNT -eq 0 ] && [ $2 -eq 1 ]; then
75    echo "No match"
76  fi
77  \rm -f $TEMP_FILE >/dev/null 2>&1
78}
79
80# Prepares the query string
81preparequery()
82{
83  local ARGS=""
84  local LAST_ARG=""
85
86  for ARG in `echo $@` ;
87  do
88    ARGS="$ARGS path:$ARG"
89    LAST_ARG="$ARG"
90  done
91
92  if [ -z "$LAST_ARG" ]; then
93    return
94  fi
95
96  PATHS_ONLY_STRING=$ARGS
97  # Assume the last path is the name of the final directory
98  PATHS_AND_FILE_STRING=`echo $ARGS | sed -e "s/path:$LAST_ARG/file:$LAST_ARG/g"`
99
100  runsearch "$PATHS_AND_FILE_STRING" 1
101  if [ $MATCHES_COUNT -eq 0 ]; then
102    # That assumption doesn't seem correct
103    runsearch "$PATHS_ONLY_STRING" 1
104  fi
105}
106
107# Warn if not sourced
108BASE_NAME=`basename $0`
109if [ "$BASE_NAME" == "pinot-cd.sh" ]; then
110  echo "Run this script with . $0"
111  exit 1
112fi
113
114checkprograms
115checkindex
116
117if [ $# == 0 ]; then
118  echo "Usage: $0 PATH1 PATH2..."
119elif [ "$MISSING_PROGRAM" == 0 ] || [ "$MISSING_INDEX" == 0 ]; then
120  if [ $# -eq 1 ] && [ "$1" == "-" ] && [ ! -z "$OLDPWD" ]; then
121    cd "$OLDPWD"
122  else
123    IS_FULL_PATH=`echo "$@" | grep "/"`
124    if [ ! -z "$IS_FULL_PATH" ]; then
125      cd $@
126    else
127      preparequery $@
128    fi
129  fi
130fi
131
132