scroll # include this from .bashrc, .zshrc or #another shell startup file with: # source$HOME/.shellfishrc # # Running from SecureShellFish # this gives access to: # openUrl toopen pages or deeps links # pbcopy to copytext to iOS clipboard # pbpaste to paste fromiOS clipboard # quicklook to preview files #runShortcut to run Shortcuts # setbarcolor tochange toolbar color # sharesheet to invokeiOS share sheet # snip to add new snippets #textastic to edit files with Textastic # # Inany terminal use: # notify to postnotifications # widget to change lock/homescreen # widgets & apple watch complications ## # this part does nothing outside ShellFishif [[ "$LC_TERMINAL" = "ShellFish" ]]; thenios_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/nullios_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\\' ) elseOUTPUT=$( 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 isno $SSH_TTY' fi } ios_sequence_spaced() { if[[ -n "$TMUX" ]]; then OUTPUT=$( ios_printf'\033Ptmux;\033\033]' echo -n "$1" ios_printf'\a\033\\' ) else OUTPUT=$( ios_printf '\033]'echo -n "$1" 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 isno $SSH_TTY' fi } # prepare fifo forcommunicating result back to shellios_prepareResult() { FIFO=$(mktemp) rm -f$FIFO mkfifo $FIFO echo $FIFO } # wait forterminal to complete action ios_handleResult(){ FIFO=$1 if [ -n "$FIFO" ]; then read <$FIFO-s rm -f $FIFO if [[ $REPLY = error* ]]; thenecho "${REPLY#error=}" | base64 >&2 -d return1 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 itwithout arguments. If arguments exist insidethe Files app changes made are written back tothe server. EOF return 0 fi fiFIFO=$(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 <<EOFUsage: quicklook [FILE]... Show QuickLookpreview for files and directories.Alternatively you can pipe in text and call itwithout arguments. EOF return 0 fi fiFIFO=$(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 theFiles app to allow writing back edits. EOFelse if [ ! -e "$1" ]; then touch "$1" fiOUTPUT=$( 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 } setbarcolor() { if [[ $# -eq 0]]; then cat <<EOF Usage: setbarcolor<css-style color> Set color of terminaltoolbar color with values such as red, #f00,#ff0000, rgb(255,0,0), color(p3 1.0 0.0 0.0)EOF else OUTPUT=$( awk 'BEGIN {printf"6;settoolbar://?ver=2&color="}'ios_printBase64Component "$1" ) ios_sequence"$OUTPUT" fi } openUrl() { if [[ $# -eq 0 ]];then cat <<EOF Usage: openUrl <url> Open URLon 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() { localbaseUrl="shortcuts://run-shortcut" if [[ $1 =="--x-callback" ]]; then localbaseUrl="shortcuts://x-callback-url/run-shortcut"shift fi if [[ $# -eq 0 ]]; then cat <<EOFUsage: runShortcut [--x-callback]<shortcut-name> [input-for-shortcut] Run inShortcuts app bringing back results if--x-callback is included. EOF else localname=$(ios_printURIComponent "$1") shift if [[$* == "-" ]]; then local text=$(cat -) localinput=$(ios_printURIComponent "$text") elselocal input=$(ios_printURIComponent "$*") fiopenUrl "$baseUrl?name=$name&input=$input" fi} # copy standard input or arguments to iOSclipboard pbcopy() { OUTPUT=$( awk 'BEGIN{printf "52;c;"} ' if [ $# -eq 0 ]; thenbase64 | tr -d '\n' else echo -n "$@" | base64| tr -d '\n' fi ) ios_sequence "$OUTPUT" } #paste from iOS device clipboard to standardoutput pbpaste() { FIFO=$(ios_prepareResult)OUTPUT=$( awk 'BEGIN {printf"6;pbpaste://?ver=2&respond="}'ios_printBase64Component "$FIFO" )ios_sequence "$OUTPUT" ios_handleResult"$FIFO" } # create new snippets snip() { if [[$# -eq 0 ]]; then cat <<EOF Usage: snip <textfor snippet> EOF else OUTPUT=$( awk 'BEGIN{printf "6;addsnippet://?ver=2&text="}'ios_printBase64Component "$*" ) ios_sequence"$OUTPUT" fi } # Secure ShellFish supports24-bit colors export COLORTERM=truecolor # Weneed to pass through escape sequences throughtmux if [[ -n "$TMUX" ]]; then # ignore errorfrom old versions of tmux without this commandtmux 2> /dev/null set -g allow-passthrough on|| true fi if [[ -z "$INSIDE_EMACS" && $- =*i* ]]; then # tmux mouse mode enablesscrolling with # swipe and mouse wheel if [[-n "$TMUX" ]]; then tmux set -g mouse on fi #send the current directory using OSC 7 whenshowing prompt to # make filename detectionwork better for interactive shellupdate_terminal_cwd() { ios_sequence $( awk"BEGIN {printf \"7;%s\",\"file://$HOSTNAME\"}" ios_printURIComponent"$PWD" ) } if [ -n "$ZSH_VERSION" ]; thenprecmd() { update_terminal_cwd; } elif [[$PROMPT_COMMAND != *"update_terminal_cwd"* ]];thenPROMPT_COMMAND="update_terminal_cwd${PROMPT_COMMAND:+;$PROMPT_COMMAND}" fi fi fi # this part worksin any context # Updates Terminal Data widgetin Secure ShellFish # # This command sendsencrypted data through push notifications such# that it doesn't need to run from a SecureShellFish terminal. widget() { if [[ $# -eq 0]]; then cat <<EOF Usage: widget [target]<data> ... Update widget on device from whichthis function was installed with a number ofcontent parameters that can be string,progress, icon, target or color. Each argumenttype is derived from input, where the firstargument is assumed to be a target if itmatches a target configured on the widget.Progress has the form: 50% or 110/220 Iconmust match valid SF Symbol name such as globeor terminal.fill Colors must be hex colourssuch as #000 #ff00ff where the color is usedfor later content and 'foreground' switchesback to default colour Target is used to senddifferent content to different widgets afterconfiguring the widgets with different targetidentifiers which requires the pro unlock. Thetarget parameter is never assumed unless--target is used and is effective until next--target parameter allowing updates of severalwidgets with a single command String is thefallback type if nothing else matches, butcontent type can be forced for next parameterwith --progress, --icon, --color, --text or--target with something like: widget --text"50/100" You can update several widgets atonce by using --target to send all parametersuntil the next --target to a particularwidget. Updating several widgets at onceallows more total updates per day. EOF return0 fi localkey=6f807b4e5864fe382ea4a13b163fec96ae413f8987090f62b6b9a1e2d0f53b1clocaluser=HrA0B1XYdMRmUkRXJHkK9FSEddEJHZdyhrBBQiZMlocal iv=ab5bbeb426015da7eedcee8bee3dffb7local plain=$( echo Secure ShellFish Widget1.0 for var in "$@" do echo "$var" done) localbase64=$(echo "$plain" | openssl enc-aes-256-cbc -base64 -K $key -iv $iv) curl -sS-X POST -H "Content-Type: text/plain" --data"$base64""https://secureshellfish.app/push/?user=$user"} # Shows notification on your device withSecure ShellFish installed. # # This commandsends encrypted data through pushnotifications such # that it doesn't need torun from a Secure ShellFish terminal. notify(){ if [[ $# -eq 0 ]]; then cat <<EOF Usage:notify [title] <body> ... EOF return 0 filocalkey=6f807b4e5864fe382ea4a13b163fec96ae413f8987090f62b6b9a1e2d0f53b1clocaluser=HrA0B1XYdMRmUkRXJHkK9FSEddEJHZdyhrBBQiZMlocal iv=ab5bbeb426015da7eedcee8bee3dffb7local plain=$( echo Secure ShellFish Notify1.0 for var in "$@" do echo "$var" done) localbase64=$(echo "$plain" | openssl enc-aes-256-cbc -base64 -K $key -iv $iv) curl -sS-X POST -H "Content-Type: text/plain" --data"$base64""https://secureshellfish.app/push/?user=$user"} ) } ) } ) } ) } ) } ) } } ) } ) } ) } ) } )} } } ) ) } ) ) } } } }