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

View File

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