From dd8480215954ca357f2c3371d86921419c0ca2e0 Mon Sep 17 00:00:00 2001 From: Toby Vincent Date: Mon, 17 Oct 2022 20:26:25 -0500 Subject: feat(tmux): split out timestamp and preview and clean up sessionzier --- tmux/.local/bin/previewer.sh | 114 +++++++++++++++++++++++++++++++ tmux/.local/bin/timestamp.sh | 143 +++++++++++++++++++++++++++++++++++++++ tmux/.local/bin/tmux-sessionizer | 69 +++---------------- 3 files changed, 268 insertions(+), 58 deletions(-) create mode 100755 tmux/.local/bin/previewer.sh create mode 100755 tmux/.local/bin/timestamp.sh (limited to 'tmux/.local') diff --git a/tmux/.local/bin/previewer.sh b/tmux/.local/bin/previewer.sh new file mode 100755 index 0000000..d064a09 --- /dev/null +++ b/tmux/.local/bin/previewer.sh @@ -0,0 +1,114 @@ +#!/bin/sh +# shellcheck disable=2046 + +SCRIPT="$(basename "$0")" + +long='remote,verbose,help' +short='rvh' + +if ! opts="$(getopt -o $short -l $long -n "$SCRIPT" -- "$@")"; then + exit 1 +fi + +eval set -- "$opts" + +help() { + cat <<-EOF + $SCRIPT + Toby Vincent + + $SCRIPT + Shows preview of a directory. Designed to be used with fzf's '--preview'. + + USAGE: + $SCRIPT [OPTION ...] [PATH ...] + + OPTIONS: + -r, --remote Treat path as a remote repository + -v, --verbose Increase verbosity + -h, --help Show this help + EOF +} + +say() { + printf "%s: %s\n" "$SCRIPT" "$@" +} + +say_verbose() { + if [ "$verbose" -gt "0" ]; then + say "$@" + fi +} + +say_err() { + say "$@" >&2 +} + +err() { + err_dir="$1" + shift + say_err "cannot preview '$err_dir': $*" + exit 1 +} + +err_help() { + help + err "$*" +} + +verbose=0 +remote=false +width=$(((($(tput cols) * 3) + (4 - 1)) / 4)) +while true; do + case "$1" in + -h | --help) + help + exit 0 + ;; + -v | --verbose) + verbose=$((verbose + 1)) + shift + ;; + -r | --remote) + remote=true + shift + ;; + -w | --width) + width=$2 + shift 2 + ;; + --) + shift + break + ;; + *) + err_help "Invalid argument: $1" + ;; + esac +done + +show_logo="always" +if [ "$width" -lt 80 ]; then + show_logo="never" +fi + +if [ "$#" -eq 0 ]; then + IFS=' +' + set -o noglob + set -- $(cat) +fi + +while [ $# -gt 0 ]; do + if $remote; then + hut git show --repo "$1" 2>/dev/null || + gh repo view "$1" 2>/dev/null || + err "$1" "Failed to find remote repository" + else + onefetch --hidden --show-logo="$show_logo" "$1" 2>/dev/null || + ([ -e "$1"/README.md ] && glow --local --style=dark "$1"/README.md) 2>/dev/null || + exa --tree --git-ignore --level=3 --icons "$1" 2>/dev/null || + err "$1" "Failed to preview directory" + fi + shift +done diff --git a/tmux/.local/bin/timestamp.sh b/tmux/.local/bin/timestamp.sh new file mode 100755 index 0000000..752c1a5 --- /dev/null +++ b/tmux/.local/bin/timestamp.sh @@ -0,0 +1,143 @@ +#!/bin/sh +# shellcheck disable=2046 + +SCRIPT="$(basename "$0")" + +long='git,sessions::,format:,verbose,help' +short='gs::f:vh' + +if ! opts="$(getopt -o $short -l $long -n "$SCRIPT" -- "$@")"; then + exit 1 +fi + +eval set -- "$opts" + +help() { + cat <<-EOF + $SCRIPT + Toby Vincent + + $SCRIPT + Get a timestamp for a given directory using multiple activity sources. By default, uses stat. + + USAGE: + $SCRIPT [OPTION ...] [PATH ...] + + OPTIONS: + -g, --git Check last git commit for timestamp + -s, --sessions=[PATH] Check nvim sessions directory for existing session files. + (DEFAULT="$XDG_DATA_HOME/nvim/sessions") + + -f, --format= Format string for output. '{}' will be replaced directory + timestamp and '{1}' will be replaced directory path + + -v, --verbose Increase verbosity + -h, --help Show this help + EOF +} + +say() { + printf "%s: %s\n" "$SCRIPT" "$@" +} + +say_verbose() { + if [ "$verbose" -gt "0" ]; then + say "$@" + fi +} + +say_err() { + say "$@" >&2 +} + +err() { + err_dir="$1" + shift + say_err "cannot timestamp '$err_dir': $*" + exit 1 +} +err_help() { + help + err "$*" +} + +verbose=0 +git=false +sessions=false +sessions_dir="$XDG_DATA_HOME/nvim/sessions" +format="{}" +while true; do + case "$1" in + -h | --help) + help + exit 0 + ;; + -v | --verbose) + verbose=$((verbose + 1)) + shift + ;; + -e | --git) + git=true + shift + ;; + -s | --sessions) + sessions=true + if [ -n "$2" ]; then + sessions_dir="$2" + fi + shift 2 + ;; + -f | --format) + format="$2" + shift 2 + ;; + --) + shift + break + ;; + *) + err_help "Invalid argument: $1" + ;; + esac +done + +if [ "$#" -eq 0 ]; then + IFS=' +' + set -o noglob + set -- $(cat) +fi + +while [ $# -gt 0 ]; do + if [ ! -d "$1" ]; then + say_err "$1" "No such file or directory" + shift + continue + fi + + ts_max="0" + if ts=$(stat -c "%Y" "$1"); then + say_verbose "stat '$1': $ts" + if [ "$ts" -gt "$ts_max" ]; then + ts_max=$ts + fi + fi + + if $git && ts=$(git -C "$1" --no-pager log -1 --all --format="%at" 2>/dev/null); then + say_verbose "git '$1': $ts" + if [ "$ts" -gt "$ts_max" ]; then + ts_max=$ts + fi + fi + + pattern=$(printf %s\\n "$1" | sed 's|/|.{1,2}|g') + if $sessions && ts=$(fd "$pattern" "$sessions_dir" -1 --type=f --max-depth=1 -x stat -c "%Y" {} 2>/dev/null); then + say_verbose "session '$1': $ts" + if [ "$ts" -gt "$ts_max" ]; then + ts_max=$ts + fi + fi + + printf %s\\n "$format" | sed "s|{}|$ts_max|g" | sed "s|{1}|$1|g" + shift +done diff --git a/tmux/.local/bin/tmux-sessionizer b/tmux/.local/bin/tmux-sessionizer index 7fe14d7..04f8633 100755 --- a/tmux/.local/bin/tmux-sessionizer +++ b/tmux/.local/bin/tmux-sessionizer @@ -2,67 +2,20 @@ # shellcheck disable=2016,2089 PROJECT_DIR="$HOME/src" -INITIAL_DIRS="$HOME/.dotfiles" -{ PREVIEW_CMD=$(cat); } <<'EOF' -selection={} -query=$(printf %s\\n {q} | sed 's|/$||') -width=$(((($(tput cols) * 3) + (4 - 1)) / 4)) -ofargs=$([ "$width" -gt 80 ] || echo "--show-logo=never") -if [ -n "$selection" ]; then - timeout 1s onefetch --hidden $ofargs $selection 2>/dev/null || - ([ -e $selection/README.md ] && timeout 1s glow --local --style=dark $selection/README.md) || - timeout 1s exa --tree --git-ignore --level=3 --icons $selection -elif [ -n "$query" ]; then - timeout 3s hut git show --repo "$query" 2>/dev/null || - timeout 3s gh repo view "$query" 2>/dev/null -fi -EOF +SESSION_DIR="$XDG_DATA_HOME/nvim/sessions" +PREVIEW_CMD="previewer.sh {} 2>/dev/null || previewer.sh {q} --remote" +ATTACHED="$(tmux list-sessions -F '#{?session_attached,#{session_path},}' 2>/dev/null | sed '/^$/d')" if [ "$#" -eq 0 ]; then - DIRS="" - - for initial_dir in $INITIAL_DIRS; do - if [ -d "$initial_dir" ]; then - DIRS="$DIRS $(stat -c %Y:"$initial_dir" "$initial_dir")" - fi - done - - for project in "$PROJECT_DIR"/*; do - if [ -d "$project" ]; then - DIRS="$DIRS $(stat -c %Y:"$project" "$project")" - fi - done - - for session in "$XDG_DATA_HOME/nvim/sessions"/*; do - entry="$(printf %s\\n "$session" | sed "s|^$XDG_DATA_HOME/nvim/sessions/||" | sed 's#%{2}|_{2}#/#g')" - if [ -d "$entry" ]; then - DIRS="$DIRS $(stat -c %Y:"$entry" "$session")" - fi - done - - if [ -n "$TMUX" ]; then - attached="$(tmux list-sessions -F '#{?session_attached,#{session_path},}' | sed '/^$/d')" - fi - - DIRS="$(printf %s\\n "$DIRS" | xargs -I{} -d ' ' sh -c ' - timestamp="$(printf %s "{}" | cut -d":" -f1)" - dir_path="$(printf %s "{}" | cut -d":" -f2)" - source="$(printf %s "{}" | cut -d":" -f2)" - - if [ -e "$dir_path/.git" ]; then - git_timestamp="$(git -C "$dir_path" --no-pager log -1 --all --format="%at" 2>/dev/null || stat -c %Y "$dir_path"/.git)" - fi - - if [ $git_timestamp -gt $timestamp ]; then - printf %s:%s\\n $git_timestamp $dir_path - else - printf %s\\n {} - fi - ' | sort -r | sort -t':' -r -k2 | uniq -s10 | sort -r | cut -d':' -f2 | sed "s#^$attached\$##g" | sed '/^$/d')" - # shellcheck disable=2046 - set -- $(printf %s\\n "$DIRS" | fzf-tmux -p -- --multi --print-query -d/ --with-nth -1 \ - --preview-window=right,75% --preview="$PREVIEW_CMD" | tr -s '\n' ' ') + set -- $({ + printf %s\\n "$HOME/.dotfiles" + fd . "$PROJECT_DIR" --type=d --max-depth=1 + fd . "$SESSION_DIR" --type=f --max-depth=1 | sed "s|^$SESSION_DIR/||" | sed 's#%%\|__#/#g' + } | sed 's|/$||' | sed "\|^$HOME\$|d" | sed "\|^$ATTACHED\$|d" | sort -u | + timestamp.sh --git --sessions="$SESSION_DIR" --format="{}:{1}" | sort -r | cut -d':' -f2 | + fzf-tmux -p -- --multi --print-query -d/ --with-nth -1 --preview-window=right,75% --preview="$PREVIEW_CMD" | + tr -s '\n' ' ') fi while [ $# -gt 0 ]; do -- cgit v1.2.3-70-g09d2