My Scripts.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
bin/tagd

154 lines
2.8 KiB

#!/bin/bash
# tagd is a simple script that will rebuild ctag files when files are edited.
# This script also acts as a wrapper for ctags.
# Author: Skiqqy
set -B
files=( )
usage ()
{
cat << EOF
tagd ~ The ctags daemon.
Usage: tagd [options]
Options
-------
-h Shows this message.
-o Specify where the tags file should be put (default is curr directory).
-s Specify the source directory that ctags must generate tags for (default is crr directory).
-g Generate ctags and then exit.
-r How often to refresh the tags file (in seconds).
-R Recursively the directory (identical to ctags -R).
-d Daemonize.
EOF
}
# set ${files[@]} to contain files in src with thier edited times.
set_files ()
{
files=( )
res=$(stat -c "%y|%n" "$src"/{*.c,*.h} | sort -r) # The sort is so when looping over the array if a time is found less than the last $iter the loop may exit (this is an optimization).
IFS=$'\n'
for file in $res # I want splitting.
do
files+=( "$file" )
done
IFS=" " # Reset IFS
}
# Usage: build <options> <output dir> <source dir>
build ()
{
echo "Building tags file."
ctags $1 "$3/"* # I want splitting
if [ ! "$2" = "$(pwd)" ]
then
mv tags "$2"
fi
}
# Convert a date.
# Usage: conv_date <date>
conv_date() {
date --date="$1" +"%Y-%m-%d %H:%M:%S"
}
# Usage: comp_date <date1> <date2>
# Returns 0 if date1 < date 2, 1 date2 < date1
comp_date ()
{
[[ $(conv_date "$1") < $(conv_date "$2") ]]
}
main ()
{
# Vars
tags=$(pwd)
src=.
daemonize=false # TODO: Implement daemonize feature.
gen=false
iter=$(date)
refresh=60
copts=
while getopts "ho:s:dgr:R" opt
do
case $opt in
h)
usage
exit
;;
o)
tags=$(realpath "$OPTARG")
if [ ! -d "$OPTARG" ]
then
echo "-o must specify a valid directory."
exit 1
fi
;;
s)
src=$(realpath "$OPTARG")
if [ ! -d "$OPTARG" ]
then
echo "-s must specify a valid directory."
exit 1
fi
;;
d)
daemonize=true
;;
g)
gen=true
;;
r)
if [[ ! "$OPTARG" =~ ^[0-9]+(\.[0-9]+)?$ ]] || [[ "$OPTARG" =~ ^0(\.0*)?$ ]]
then
echo "-r must be a non zero real."
exit 1
fi
refresh="$OPTARG"
;;
R)
copts="-R"
;;
*)
usage
exit 1
;;
esac
done
# Build tags file before starting main loop.
build "$copts" "$tags" "$src"
if "$gen"
then
exit
fi
# Start
for ((;;))
do
sleep "$refresh"
set_files
for file in "${files[@]}"
do
time=$(echo "$file" | cut -d "|" -f 1 | cut -d\. -f 1)
file=$(echo "$file" | cut -d "|" -f 2)
if comp_date "$iter" "$time"
then
echo "Change detected!"
iter=$(date)
build "$copts" "$tags" "$src"
break # Yes I know that techinically we only have to look at the first item, but this loop is to allow for the script to be extended.
fi
done
done
}
main "$@"