From 164142dd4342564a644aaa41e3ac4d73008ce7c0 Mon Sep 17 00:00:00 2001 From: Ethan P Date: Fri, 2 Apr 2021 16:17:07 -0700 Subject: [PATCH] batwatch: Add mode for watching command output --- doc/batwatch.md | 23 +++++---- src/batwatch.sh | 123 ++++++++++++++++++++++++++++++------------------ 2 files changed, 91 insertions(+), 55 deletions(-) diff --git a/doc/batwatch.md b/doc/batwatch.md index 949b6e6..42299ee 100644 --- a/doc/batwatch.md +++ b/doc/batwatch.md @@ -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.
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.
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. diff --git a/src/batwatch.sh b/src/batwatch.sh index 0565acc..4406a64 100755 --- a/src/batwatch.sh +++ b/src/batwatch.sh @@ -28,7 +28,8 @@ hook_help # Help: # ----------------------------------------------------------------------------- show_help() { - echo 'Usage: batwatch [--watcher entr|poll][--[no-]clear] [ ...]' + echo 'Usage: batwatch --file [--watcher entr|poll][--[no-]clear] [ ...]' + echo ' batwatch --command [-n] [ ...]' } # ----------------------------------------------------------------------------- # 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 - - if [[ -d "$file" ]]; then - FILES_HAS_DIRECTORY=true - fi -done + +# 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 +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 +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 + + main() { + "watcher_${OPT_WATCHER}_watch" "${FILES[@]}" + return $? + } 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 + 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 $?