5 Commits 3b153b8d5f ... 6e1396bb75

Tác giả SHA1 Thông báo Ngày
  Daniel Sheffield 6e1396bb75 add note to allow configuring null terminated output 9 tháng trước cách đây
  Daniel Sheffield e3e291cca6 allow multiselect 9 tháng trước cách đây
  Daniel Sheffield 3b8fbca8d6 print full path to logs 9 tháng trước cách đây
  Daniel Sheffield d332cea0b0 add support for limiting list length and ensure fzf query takes part in find command 9 tháng trước cách đây
  Daniel Sheffield e53b4ef398 add ability to search and preview capture history 9 tháng trước cách đây
1 tập tin đã thay đổi với 124 bổ sung27 xóa
  1. 124 27
      recall.sh

+ 124 - 27
recall.sh

@@ -7,32 +7,129 @@ then
 fi
 LOG_ROOT="$HOME"/.local/var/log/shell # source this
 
-SUBPROG=""
-PROG="$1"
-
-#TODO: eval, really?
-#      not fully working anyway (aliases, functions)
-#while [ "$(eval "$PROG")" == "capture" ]
-#do
-	#TODO: eval not sufficient if
-	#      capture is aliased
-	#      or invoked by a function
-#	shift 1; PROG=$1;
-#done
-
-# TODO: and maybe su, runuser et al
-if [ "$PROG" == "sudo" ]
-then
-	SUBPROG="$2"
-fi
+LIST_MODE=false
+
+usage () {
+	cat <<EOF
+Recall prints the last captured output from the specified PROG and exits with
+the captured exit status.
+
+  usage: "${0##*/} [ -l ] [ -n NUM ] PROG [ ARGS ... ]
+
+  examples:
+    - Print the output of last captured find command
+
+      ${0##*/} find
+
+    - List paths to all captured commands
+
+      ${0##*/} -l
 
-LOG_DIR="$LOG_ROOT"/"$PROG"/"$SUBPROG"
-LOG_DIR="$LOG_DIR"/"$(ls -1 "$LOG_DIR" | sort -V | tail -n1)"
+    - List paths to all captured find commands
 
-OUT="$LOG_DIR"/stdout
-ERR="$LOG_DIR"/stderr
-DAT="$LOG_DIR"/dat
-INF="$LOG_DIR"/info
-. <(tail -n +2 "$INF")
-cat "$OUT"
-exit "$status"
+      ${0##*/} -l find
+EOF
+}
+
+OPTSTRING=":hln:"
+parse_opt () {
+	case "${opt}" in
+		h)
+			usage
+			exit 0
+		;;
+		l)
+			LIST_MODE=true
+		;;
+		n)
+			if [ "${OPTARG:-}" ] && [[ "$OPTARG" =~ [0-9]+ ]] && (( OPTARG > 0 ))
+			then
+				NUM="$OPTARG"
+			else
+				echo "-n paremeter must be an integer greater than zero" >&2
+				echo >&2
+				usage >&2
+				exit 1
+			fi
+		;;
+		\?)
+			echo "Unknown switch: -$OPTARG" >&2
+			echo >&2
+			usage >&2
+			exit 1
+		;;
+	esac
+}
+
+validate () {
+	# exit if vars are not valid
+	# ie, set any dynamic defaults here
+	if ! "$LIST_MODE" && [ "${NUM:=1}" ] && ! (( NUM == 1 ))
+	then
+		echo "-n != 1 can only be specified with -l" >&2
+		echo >&2
+		usage >&2
+		exit 1
+	fi
+	if ! "$LIST_MODE" && [ "$#" == "0" ]
+	then
+		echo "PROG must be provided" >&2
+		echo >&2
+		usage >&2
+		exit 1
+	fi
+}
+
+while getopts "${OPTSTRING}" opt
+do
+	parse_opt
+done
+shift $((OPTIND-1))
+
+validate "$@"
+
+if "$LIST_MODE"
+then
+	fzf_query=()
+	find_name=()
+	if [ "${1:-}" ]
+	then
+		fzf_query=( "--query=$1" )
+		find_name=( -wholename "**/$1/**" )
+	fi
+	(
+		cd "$LOG_ROOT"
+		find . \
+			\( -type l -o -type d \) -wholename './????????_??????_?????????' -prune -o -type d "${find_name[@]}" \( \
+				-links 2 \
+				-o \( \
+					-links 1 -exec bash -c '! [ "$(find "$1" -mindepth 1 -type d)" ]' find-bash {} \; \
+				\) \
+			\) \
+			-print0 \
+		| sort -zV \
+		| head -zn "${NUM:--0}" \
+		| fzf --read0 --print0 -m --no-sort "${fzf_query[@]}" -d / --nth 1,2,3 --preview='cat {}/info; head {}/dat' \
+		| awk -v RS='\0' -v FS='/' -v OFS='/' -v ORS='\0' '{for (i=2; i<=NF; i++) printf "%s%s", $(i), (i<NF ? OFS : ORS)}' \
+		| awk -v prefix="$LOG_ROOT/" -v RS='\0' -v ORS='\n' '{print prefix $0}' \
+		: "TODO: allow configuring null terminated output"
+	)
+else
+	SUBPROG=""
+	PROG="$1"
+
+	# TODO: and maybe su, runuser et al
+	if [ "$PROG" == "sudo" ]
+	then
+		SUBPROG="$2"
+	fi
+	LOG_DIR="$LOG_ROOT"/"$PROG"/"$SUBPROG"
+	LOG_DIR="$LOG_DIR"/"$(ls -1 "$LOG_DIR" | sort -V | tail -n1)"
+	OUT="$LOG_DIR"/stdout
+	ERR="$LOG_DIR"/stderr
+	DAT="$LOG_DIR"/dat
+	INF="$LOG_DIR"/info
+	. <(tail -n +2 "$INF")
+	cat "$OUT"
+	exit "$status"
+fi