batwatch: Add mode for watching command output

This commit is contained in:
Ethan P 2021-04-02 16:17:07 -07:00
parent e16e05d1d4
commit 164142dd43
No known key found for this signature in database
GPG Key ID: 6963FD04F6CF35EA
2 changed files with 91 additions and 55 deletions

View File

@ -1,8 +1,6 @@
# bat-extras: batwatch
Watch for changes in one or more files, and print them with `bat`.
Please note this watches filesystem files, and not command output like `watch(1)`.
Watch for changes in files or command output, and print them with `bat`.
@ -10,17 +8,22 @@ Please note this watches filesystem files, and not command output like `watch(1)
batwatch [OPTIONS] FILE...
batwatch [OPTIONS] --command COMMAND [ARG...]
## Options
| Short | Long | Description |
| ----- | --------------------- | ------------------------------------------------------------ |
| | `--watcher=[watcher]` | Use a specific program to watch for file changes. See [below](#watchers) for more details. |
| | `--clear` | Clear the screen before printing the files.<br />This is enabled by default. |
| | `--no-clear` | Do not clear the screen before printing the files. |
| | `--color` | Force color output. |
| | `--no-color` | Force disable color output. |
| Short | Long | Description |
| ----- | ---------------------- | ------------------------------------------------------------ |
| | `--command`\|`-x` | Execute a command on an interval. |
| | `--file`\|`-f` | Watch a file for changes. |
| | `--watcher=[watcher]` | Use a specific program to watch for file changes. See [below](#watchers) for more details. |
| | `--interval=[seconds]` | The interval for executing commands. |
| | `--clear` | Clear the screen before printing the files.<br />This is enabled by default. |
| | `--no-clear` | Do not clear the screen before printing the files. |
| | `--color` | Force color output. |
| | `--no-color` | Force disable color output. |
All remaining options are passed through to bat.

View File

@ -28,7 +28,8 @@ hook_help
# Help:
# -----------------------------------------------------------------------------
show_help() {
echo 'Usage: batwatch [--watcher entr|poll][--[no-]clear] <file> [<file> ...]'
echo 'Usage: batwatch --file [--watcher entr|poll][--[no-]clear] <file> [<file> ...]'
echo ' batwatch --command [-n<interval>] <command> [<arg> ...]'
}
# -----------------------------------------------------------------------------
# Watchers:
@ -107,11 +108,7 @@ watcher_poll_watch() {
while true; do
if "$modified"; then
modified=false
if [[ "$OPT_CLEAR" == "true" ]]; then
clear
fi
clear
pager_exec "$EXECUTABLE_BAT" "${BAT_ARGS[@]}" \
--terminal-width="$OPT_TERMINAL_WIDTH" \
--paging=never \
@ -132,9 +129,9 @@ watcher_poll_watch() {
((i++))
done
# Wait for "q" to exit, or check again after 1 second.
# Wait for "q" to exit, or check again after a few seconds.
local input
read -r -t 1 input
read -r -t "${OPT_INTERVAL}" input
if [[ "$input" =~ [q|Q] ]]; then
exit
fi
@ -171,7 +168,8 @@ determine_watcher() {
BAT_ARGS=()
FILES=()
FILES_HAS_DIRECTORY=false
OPT_HELP=false
OPT_MODE=file
OPT_INTERVAL=3
OPT_CLEAR=true
OPT_WATCHER=""
@ -185,10 +183,10 @@ while shiftopt; do
case "$OPT" in
# Script options
--watcher)
shiftval
OPT_WATCHER="$OPT_VAL"
;;
--watcher) shiftval; OPT_WATCHER="$OPT_VAL" ;;
--interval|-n) shiftval; OPT_INTERVAL="$OPT_VAL" ;;
--file|-f) OPT_MODE=file ;;
--command|-x) OPT_MODE=command ;;
--clear) OPT_CLEAR=true ;;
--no-clear) OPT_CLEAR=false ;;
@ -198,26 +196,38 @@ while shiftopt; do
# Files
*) {
FILES+=("$OPT")
if [[ "$OPT_MODE" = "command" ]]; then
getargs --append FILES
break
fi
} ;;
esac
done
# Validate that a file/command was provided.
if [[ ${#FILES[@]} -eq 0 ]]; then
print_error "no files provided"
if [[ "$OPT_MODE" = "file" ]]; then
print_error "no files provided"
else
print_error "no command provided"
fi
exit 1
fi
for file in "${FILES[@]}"; do
if ! [[ -e "$file" ]]; then
print_error "'%s' does not exist" "$file"
exit 1
fi
# Validate that the provided files exist.
if [[ "$OPT_MODE" = "file" ]]; then
for file in "${FILES[@]}"; do
if ! [[ -e "$file" ]]; then
print_error "'%s' does not exist" "$file"
exit 1
fi
if [[ -d "$file" ]]; then
FILES_HAS_DIRECTORY=true
fi
done
if [[ -d "$file" ]]; then
FILES_HAS_DIRECTORY=true
fi
done
fi
# Append bat arguments.
if "$OPT_COLOR"; then
@ -226,33 +236,56 @@ else
BAT_ARGS+=("--color=never")
fi
# Initialize clear command based on whether or not ANSI should be used.
if [[ "$OPT_CLEAR" == "true" ]]; then
if "$OPT_COLOR"; then
clear() {
term_clear || return $?
}
fi
else
clear() {
:
}
fi
# -----------------------------------------------------------------------------
# Main:
# -----------------------------------------------------------------------------
# Determine the watcher.
if [[ -z "$OPT_WATCHER" ]]; then
if ! determine_watcher; then
print_error "Your system does not have any supported watchers."
printc "Please read the documentation at %{BLUE}%s%{CLEAR} for more details.\n" "$PROGRAM_HOMEPAGE" 1>&2
exit 2
fi
else
if ! type "watcher_${OPT_WATCHER}_supported" &> /dev/null; then
print_error "Unknown watcher: '%s'" "$OPT_WATCHER"
exit 1
if [[ "$OPT_MODE" = "file" ]]; then
# Determine the watcher.
if [[ -z "$OPT_WATCHER" ]]; then
if ! determine_watcher; then
print_error "Your system does not have any supported watchers."
printc "Please read the documentation at %{BLUE}%s%{CLEAR} for more details.\n" "$PROGRAM_HOMEPAGE" 1>&2
exit 2
fi
else
if ! type "watcher_${OPT_WATCHER}_supported" &> /dev/null; then
print_error "Unknown watcher: '%s'" "$OPT_WATCHER"
exit 1
fi
if ! "watcher_${OPT_WATCHER}_supported" &> /dev/null; then
print_error "Unsupported watcher: '%s'" "$OPT_WATCHER"
exit 1
fi
fi
if ! "watcher_${OPT_WATCHER}_supported" &> /dev/null; then
print_error "Unsupported watcher: '%s'" "$OPT_WATCHER"
exit 1
fi
main() {
"watcher_${OPT_WATCHER}_watch" "${FILES[@]}"
return $?
}
else
main() {
while true; do
clear
"${FILES[@]}" 2>&1 | bat
sleep "${OPT_INTERVAL}" || exit 1
done
}
fi
# Run the main function.
main() {
"watcher_${OPT_WATCHER}_watch" "${FILES[@]}"
return $?
}
main
exit $?