my-yadm/.shellfish

280 lines
6.6 KiB
Plaintext

# include this from .bashrc, .zshrc or
# another shell startup file with:
# source $HOME/.shellfishrc
# this script does nothing outside ShellFish
if [[ "$LC_TERMINAL" = "ShellFish" ]]; then
ios_printURIComponent() {
awk 'BEGIN {while (y++ < 125) z[sprintf("%c", y)] = y
while (y = substr(ARGV[1], ++j, 1))
q = y ~ /[a-zA-Z0-9]/ ? q y : q sprintf("%%%02X", z[y])
printf("%s", q)}' "$1"
}
ios_printBase64Component() {
echo -n "$1" | base64
}
which printf > /dev/null
ios_hasPrintf=$?
ios_printf() {
if [ $ios_hasPrintf ]; then
printf "$1"
else
awk "BEGIN {printf \"$1\"}"
fi
}
ios_sequence() {
if [[ -n "$TMUX" ]]; then
OUTPUT=$(
ios_printf '\033Ptmux;\033\033]'
echo -n "$1" | tr -d '[:space:]'
ios_printf '\a\033\\' )
else
OUTPUT=$(
ios_printf '\033]'
echo -n "$1" | tr -d '[:space:]'
ios_printf '\a' )
fi
if [ -t 1 ] ; then
echo -n $OUTPUT
elif [[ -n "$SSH_TTY" ]]; then
echo -n $OUTPUT > $SSH_TTY
else
echo >&2 'Standard output is not tty and there is no $SSH_TTY'
fi
}
# prepare fifo for communicating result back to shell
ios_prepareResult() {
FIFO=$(mktemp)
rm -f $FIFO
mkfifo $FIFO
echo $FIFO
}
# wait for terminal to complete action
ios_handleResult() {
FIFO=$1
if [ -n "$FIFO" ]; then
read <$FIFO -s
rm -f $FIFO
if [[ $REPLY = error* ]]; then
echo "${REPLY#error=}" | base64 >&2 -d
return 1
fi
if [[ $REPLY = result* ]]; then
echo "${REPLY#result=}" | base64 -d
fi
fi
}
sharesheet() {
if [[ $# -eq 0 ]]; then
if tty -s; then
cat <<EOF
Usage: sharesheet [FILE]...
Present share sheet for files and directories. Alternatively you can pipe in text and call it without arguments.
If arguments exist inside the Files app changes made are written back to the server.
EOF
return 0
fi
fi
FIFO=$(ios_prepareResult)
OUTPUT=$(
awk 'BEGIN {printf "6;sharesheet://?ver=2&respond="}'
ios_printBase64Component "$FIFO"
awk 'BEGIN {printf "&pwd="}'
ios_printBase64Component "$PWD"
awk 'BEGIN {printf "&home="}'
ios_printBase64Component "$HOME"
for var in "$@"
do
awk 'BEGIN {printf "&path="}'
ios_printBase64Component "$var"
done
if [[ $# -eq 0 ]]; then
text=$(cat -)
awk 'BEGIN {printf "&text="}'
ios_printBase64Component "$text"
fi
)
ios_sequence "$OUTPUT"
ios_handleResult "$FIFO"
}
quicklook() {
if [[ $# -eq 0 ]]; then
if tty -s; then
cat <<EOF
Usage: quicklook [FILE]...
Show QuickLook preview for files and directories. Alternatively you can pipe in text and call it without arguments.
EOF
return 0
fi
fi
FIFO=$(ios_prepareResult)
OUTPUT=$(
awk 'BEGIN {printf "6;quicklook://?ver=2&respond="}'
ios_printBase64Component "$FIFO"
awk 'BEGIN {printf "&pwd="}'
ios_printBase64Component "$PWD"
awk 'BEGIN {printf "&home="}'
ios_printBase64Component "$HOME"
for var in "$@"
do
awk 'BEGIN {printf "&path="}'
ios_printBase64Component "$var"
done
if [[ $# -eq 0 ]]; then
text=$(cat -)
awk 'BEGIN {printf "&text="}'
ios_printBase64Component "$text"
fi
)
ios_sequence "$OUTPUT"
ios_handleResult "$FIFO"
}
textastic() {
if [[ $# -eq 0 ]]; then
cat <<EOF
Usage: textastic <text-file>
Open in Textastic 9.5 or later.
File must be in directory represented in the Files app to allow writing back edits.
EOF
else
if [ ! -e "$1" ]; then
touch "$1"
fi
OUTPUT=$(
awk 'BEGIN {printf "6;textastic://?ver=2&pwd="}'
ios_printBase64Component "$PWD"
awk 'BEGIN {printf "&home="}'
ios_printBase64Component "$HOME"
awk 'BEGIN {printf "&path="}'
ios_printBase64Component "$1"
)
ios_sequence "$OUTPUT"
fi
}
openUrl() {
if [[ $# -eq 0 ]]; then
cat <<EOF
Usage: openUrl <url>
Open URL on iOS.
EOF
else
FIFO=$(ios_prepareResult)
OUTPUT=$(
awk 'BEGIN {printf "6;open://?ver=2&respond="}'
ios_printBase64Component "$FIFO"
awk 'BEGIN {printf "&url="}'
ios_printBase64Component "$1"
)
ios_sequence "$OUTPUT"
ios_handleResult "$FIFO"
fi
}
runShortcut() {
local baseUrl="shortcuts://run-shortcut"
if [[ $1 == "--x-callback" ]]; then
local baseUrl="shortcuts://x-callback-url/run-shortcut"
shift
fi
if [[ $# -eq 0 ]]; then
cat <<EOF
Usage: runShortcut [--x-callback] <shortcut-name> [input-for-shortcut]
Run in Shortcuts app bringing back results if --x-callback is included.
EOF
else
local name=$(ios_printURIComponent "$1")
shift
local input=$(ios_printURIComponent "$*")
openUrl "$baseUrl?name=$name&input=$input"
fi
}
notify() {
if [[ $# -eq 0 ]]; then
cat <<EOF
Usage: notify <title> [body]
Show notification on iOS device.
Title cannot contain semicolon.
EOF
else
local title="${1-}" body="${2-}"
OUTPUT=$(
echo $title | awk -F";" 'BEGIN {printf "777;notify;"} {printf "%s;", $1}'
echo $body
)
ios_sequence "$OUTPUT"
fi
}
# copy standard input or arguments to iOS clipboard
pbcopy() {
OUTPUT=$(
awk 'BEGIN {printf "52;c;"} '
if [ $# -eq 0 ]; then
base64 | tr -d '\n'
else
echo -n "$@" | base64 | tr -d '\n'
fi
)
ios_sequence "$OUTPUT"
}
# paste from iOS device clipboard to standard output
pbpaste() {
FIFO=$(ios_prepareResult)
OUTPUT=$(
awk 'BEGIN {printf "6;pbpaste://?ver=2&respond="}'
ios_printBase64Component "$FIFO"
)
ios_sequence "$OUTPUT"
ios_handleResult "$FIFO"
}
# Secure ShellFish supports 24-bit colors
export COLORTERM=truecolor
if [[ -z "$INSIDE_EMACS" && $- = *i* ]]; then
# tmux mouse mode enables scrolling with
# swipe and mouse wheel
if [[ -n "$TMUX" ]]; then
tmux set -g mouse on
fi
# send the current directory using OSC 7 when showing prompt to
# make filename detection work better for interactive shell
update_terminal_cwd() {
ios_sequence $(
awk "BEGIN {printf \"7;%s\", \"file://$HOSTNAME\"}"
ios_printURIComponent "$PWD"
)
}
if [ -n "$ZSH_VERSION" ]; then
precmd() { update_terminal_cwd; }
elif [[ $PROMPT_COMMAND != *"update_terminal_cwd"* ]]; then
PROMPT_COMMAND="update_terminal_cwd${PROMPT_COMMAND:+; $PROMPT_COMMAND}"
fi
fi
fi