mirror of https://git.sr.ht/~skiqqy/bin
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.
154 lines
2.8 KiB
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 "$@"
|
|
|