add iterm2 shell integration

This commit is contained in:
Förster
2017-09-19 14:45:34 +02:00
parent d2d7cf0688
commit f06a7abbff
12 changed files with 975 additions and 0 deletions

112
.iterm2/imgcat Executable file
View File

@@ -0,0 +1,112 @@
#!/bin/bash
# tmux requires unrecognized OSC sequences to be wrapped with DCS tmux;
# <sequence> ST, and for all ESCs in <sequence> to be replaced with ESC ESC. It
# only accepts ESC backslash for ST.
function print_osc() {
if [[ $TERM == screen* ]] ; then
printf "\033Ptmux;\033\033]"
else
printf "\033]"
fi
}
# More of the tmux workaround described above.
function print_st() {
if [[ $TERM == screen* ]] ; then
printf "\a\033\\"
else
printf "\a"
fi
}
# print_image filename inline base64contents print_filename
# filename: Filename to convey to client
# inline: 0 or 1
# base64contents: Base64-encoded contents
# print_filename: If non-empty, print the filename
# before outputting the image
function print_image() {
print_osc
printf '1337;File='
if [[ -n "$1" ]]; then
printf 'name='`printf "%s" "$1" | base64`";"
fi
VERSION=$(base64 --version 2>&1)
if [[ "$VERSION" =~ fourmilab ]]; then
BASE64ARG=-d
elif [[ "$VERSION" =~ GNU ]]; then
BASE64ARG=-di
else
BASE64ARG=-D
fi
printf "%s" "$3" | base64 $BASE64ARG | wc -c | awk '{printf "size=%d",$1}'
printf ";inline=$2"
printf ":"
printf "%s" "$3"
print_st
printf '\n'
if [[ -n "$4" ]]; then
echo $1
fi
}
function error() {
echo "ERROR: $*" 1>&2
}
function show_help() {
echo "Usage: imgcat [-p] filename ..." 1>& 2
echo " or: cat filename | imgcat" 1>& 2
}
## Main
if [ -t 0 ]; then
has_stdin=f
else
has_stdin=t
fi
# Show help if no arguments and no stdin.
if [ $has_stdin = f -a $# -eq 0 ]; then
show_help
exit
fi
# Look for command line flags.
while [ $# -gt 0 ]; do
case "$1" in
-h|--h|--help)
show_help
exit
;;
-p|--p|--print)
print_filename=1
;;
-*)
error "Unknown option flag: $1"
show_help
exit 1
;;
*)
if [ -r "$1" ] ; then
has_stdin=f
print_image "$1" 1 "$(base64 < "$1")" "$print_filename"
else
error "imgcat: $1: No such file or directory"
exit 2
fi
;;
esac
shift
done
# Read and print stdin
if [ $has_stdin = t ]; then
print_image "" 1 "$(cat | base64)" ""
fi
exit 0

68
.iterm2/imgls Executable file
View File

@@ -0,0 +1,68 @@
#!/bin/bash
# tmux requires unrecognized OSC sequences to be wrapped with DCS tmux;
# <sequence> ST, and for all ESCs in <sequence> to be replaced with ESC ESC. It
# only accepts ESC backslash for ST.
function print_osc() {
if [ x"$TERM" = "xscreen" ] ; then
printf "\033Ptmux;\033\033]"
else
printf "\033]"
fi
}
# More of the tmux workaround described above.
function print_st() {
if [ x"$TERM" = "xscreen" ] ; then
printf "\a\033\\"
else
printf "\a"
fi
}
function list_file() {
fn=$1
dims=$(php -r 'if (!is_file($argv[1])) exit(1); $a = getimagesize($argv[1]); if ($a==FALSE) exit(1); else { echo $a[0] . "x" .$a[1]; exit(0); }' "$fn")
rc=$?
if [[ $rc == 0 ]] ; then
print_osc
printf '1337;File=name='`echo -n "$fn" | base64`";"
wc -c "$fn" | awk '{printf "size=%d",$1}'
printf ";inline=1;height=3;width=3;preserveAspectRatio=true"
printf ":"
base64 < "$fn"
print_st
if [ x"$TERM" == "xscreen" ] ; then
# This works in plain-old tmux but does the wrong thing in iTerm2's tmux
# integration mode. tmux doesn't know that the cursor moves when the
# image code is sent, while iTerm2 does. I had to pick one, since
# integration mode is undetectable, so I picked the failure mode that at
# least produces useful output (there is just too much whitespace in
# integration mode). This could be fixed by not moving the cursor while
# in integration mode. A better fix would be for tmux to interpret the
# image sequence, though.
#
# tl;dr: If you use tmux in integration mode, replace this with the printf
# from the else clause.
printf '\033[4C\033[Bx'
else
printf '\033[A'
fi
echo -n "$dims "
ls -ld "$fn"
else
ls -ld "$fn"
fi
}
if [ $# -eq 0 ]; then
for fn in *
do
list_file "$fn"
done < <(ls -ls)
else
for fn in "$@"
do
list_file "$fn"
done
fi

71
.iterm2/it2attention Executable file
View File

@@ -0,0 +1,71 @@
#!/bin/bash
# tmux requires unrecognized OSC sequences to be wrapped with DCS tmux;
# <sequence> ST, and for all ESCs in <sequence> to be replaced with ESC ESC. It
# only accepts ESC backslash for ST.
function print_osc() {
if [[ $TERM == screen* ]] ; then
printf "\033Ptmux;\033\033]"
else
printf "\033]"
fi
}
# More of the tmux workaround described above.
function print_st() {
if [[ $TERM == screen* ]] ; then
printf "\a\033\\"
else
printf "\a"
fi
}
function show_help() {
echo "Usage:" 1>& 2
echo " $(basename $0) start" 1>& 2
echo " Begin bouncing the dock icon if another app is active" 1>& 2
echo " $(basename $0) stop" 1>& 2
echo " Stop bouncing the dock icon if another app is active" 1>& 2
echo " $(basename $0) fireworks" 1>& 2
echo " Show an explosion animation at the cursor" 1>& 2
}
function start_bounce() {
print_osc
printf "1337;RequestAttention=1"
print_st
}
function stop_bounce() {
print_osc
printf "1337;RequestAttention=0"
print_st
}
function fireworks() {
print_osc
printf "1337;RequestAttention=fireworks"
print_st
}
## Main
if [[ $# == 0 ]]
then
show_help
exit 1
fi
if [[ $1 == start ]]
then
start_bounce
elif [[ $1 == stop ]]
then
stop_bounce
elif [[ $1 == fireworks ]]
then
fireworks
else
show_help
exit 1
fi

88
.iterm2/it2check Executable file
View File

@@ -0,0 +1,88 @@
#!/bin/bash
# Make sure stdin and stdout are a tty.
if [ ! -t 0 ] ; then
exit 1
fi
if [ ! -t 1 ] ; then
exit 1
fi
# Save the tty's state.
saved_stty=$(stty -g)
# Trap ^C to fix the tty.
trap ctrl_c INT
function ctrl_c() {
stty "$saved_stty"
exit 1
}
# Read some bytes from stdin. Pass the number of bytes to read as the first argument.
function read_bytes()
{
numbytes=$1
dd bs=1 count=$numbytes 2>/dev/null
}
function read_dsr() {
# Reading response to DSR.
dsr=""
spam=$(read_bytes 2)
byte=$(read_bytes 1)
while [ "${byte}" != "n" ]; do
dsr=${dsr}${byte}
byte=$(read_bytes 1)
done
echo ${dsr}
}
# Extract the terminal name from DSR 1337
function terminal {
echo -n "$1" | sed -e 's/ .*//'
}
# Extract the version number from DSR 1337
function version {
echo -n "$1" | sed -e 's/.* //'
}
# Enter raw mode and turn off echo so the terminal and I can chat quietly.
stty -echo -icanon raw
# Support for the extension first appears in this version of iTerm2:
MIN_VERSION=2.9.20160304
if [ $# -eq 1 ]; then
MIN_VERSION=$1
fi
# Send iTerm2-proprietary code. Other terminals ought to ignore it (but are
# free to use it respectfully). The response won't start with a 0 so we can
# distinguish it from the response to DSR 5. It should contain the terminal's
# name followed by a space followed by its version number and be terminated
# with an n.
echo -n ''
# Report device status. Responds with esc [ 0 n. All terminals support this. We
# do this because if the terminal will not respond to iTerm2's custom escape
# sequence, we can still read from stdin without blocking indefinitely.
echo -n ''
version_string=$(read_dsr)
if [ "${version_string}" != "0" -a "${version_string}" != "3" ]; then
# Already read DSR 1337. Read DSR 5 and throw it away.
dsr=$(read_dsr)
else
# Terminal didn't respond to the DSR 1337. The response we read is from DSR 5.
version_string=""
fi
# Restore the terminal to cooked mode.
stty "$saved_stty"
# Extract the terminal name and version number from the response.
version=$(version "${version_string}")
term=$(terminal "${version_string}")
# Check if they match what we're looking for. This becomes the return code of the script.
test "$term" = ITERM2 -a \( "$version" \> "$MIN_VERSION" -o "$version" = "$MIN_VERSION" \)

78
.iterm2/it2copy Executable file
View File

@@ -0,0 +1,78 @@
#!/bin/bash
trap clean_up EXIT
trap clean_up INT
inosc=0
function clean_up() {
if [[ $inosc == 1 ]]
then
print_st
fi
}
function show_help() {
echo "Usage: $(basename $0)" 1>& 2
echo " Copies to clipboard from standard input" 1>& 2
echo " $(basename $0) filename" 1>& 2
echo " Copies to clipboard from file" 1>& 2
}
# tmux requires unrecognized OSC sequences to be wrapped with DCS tmux;
# <sequence> ST, and for all ESCs in <sequence> to be replaced with ESC ESC. It
# only accepts ESC backslash for ST.
function print_osc() {
if [[ $TERM == screen* ]] ; then
printf "\033Ptmux;\033\033]"
else
printf "\033]"
fi
}
# More of the tmux workaround described above.
function print_st() {
if [[ $TERM == screen* ]] ; then
printf "\a\033\\"
else
printf "\a"
fi
}
# Look for command line flags.
while [ $# -gt 0 ]; do
case "$1" in
-h|--h|--help)
show_help
exit
;;
-*)
error "Unknown option flag: $1"
show_help
exit 1
;;
*)
if [ -r "$1" ] ; then
data=$(base64 < "$1")
print_osc
inosc=1
printf '1337;Copy=:%s' "$data"
print_st
inosc=0
exit 0
else
error "it2copy: $1: No such file or directory"
exit 2
fi
;;
esac
shift
done
data=$(base64)
print_osc
inosc=1
printf '1337;Copy=:%s' "$data"
print_st
inosc=0

18
.iterm2/it2dl Executable file
View File

@@ -0,0 +1,18 @@
#!/bin/bash
if [ $# -lt 1 ]; then
echo "Usage: $(basename $0) file ..."
exit 1
fi
for fn in "$@"
do
if [ -r "$fn" ] ; then
[ -d "$fn" ] && { echo "$fn is a directory"; continue; }
printf '\033]1337;File=name='`echo -n "$fn" | base64`";"
wc -c "$fn" | awk '{printf "size=%d",$1}'
printf ":"
base64 < "$fn"
printf '\a'
else
echo File $fn does not exist or is not readable.
fi
done

99
.iterm2/it2getvar Executable file
View File

@@ -0,0 +1,99 @@
#!/bin/bash
function ctrl_c() {
stty "$saved_stty"
exit 1
}
# tmux requires unrecognized OSC sequences to be wrapped with DCS tmux;
# <sequence> ST, and for all ESCs in <sequence> to be replaced with ESC ESC. It
# only accepts ESC backslash for ST.
function print_osc() {
if [[ $TERM == screen* ]] ; then printf "\033Ptmux;\033\033]"
else
printf "\033]" >& 2
fi
}
# More of the tmux workaround described above.
function print_st() {
if [[ $TERM == screen* ]] ; then
printf "\a\033\\" >& 2
else
printf "\a" >& 2
fi
}
function show_help() {
echo "Usage:" 1>& 2
echo " $(basename $0) name" 1>& 2
}
# Read some bytes from stdin. Pass the number of bytes to read as the first argument.
function read_bytes() {
numbytes=$1
dd bs=1 count=$numbytes 2>/dev/null
}
# read_until c
# Returns bytes read from stdin up to but not including the fist one equal to c
function read_until() {
result=""
while :
do
b=$(read_bytes 1)
if [[ $b == $1 ]]
then
echo "$result"
return
fi
result="$result$b"
done
}
## Main
if [[ $# != 1 ]]
then
show_help
exit 1
fi
if ! test -t 1
then
echo "Standard error not a terminal"
exit 1
fi
# Save the tty's state.
saved_stty=$(stty -g)
# Trap ^C to fix the tty.
trap ctrl_c INT
# Enter raw mode and turn off echo so the terminal and I can chat quietly.
stty -echo -icanon raw
print_osc
printf "1337;ReportVariable=%s" "$(printf "%s" "$1" | base64)" >& 2
print_st
VERSION=$(base64 --version 2>&1)
if [[ "$VERSION" =~ fourmilab ]]; then
BASE64ARG=-d
elif [[ "$VERSION" =~ GNU ]]; then
BASE64ARG=-di
else
BASE64ARG=-D
fi
ignore=$(read_bytes 1)
name=$(read_until )
re='^]1337;ReportVariable=(.*)'
if [[ $name =~ $re ]]
then
printf "%s" $(base64 $BASE64ARG <<< ${BASH_REMATCH[1]})
exit 0
else
exit 1
fi

116
.iterm2/it2setcolor Executable file
View File

@@ -0,0 +1,116 @@
#!/bin/bash
open=0
# tmux requires unrecognized OSC sequences to be wrapped with DCS tmux;
# <sequence> ST, and for all ESCs in <sequence> to be replaced with ESC ESC. It
# only accepts ESC backslash for ST.
function print_osc() {
if [[ $TERM == screen* ]] ; then
printf "\033Ptmux;\033\033]"
else
printf "\033]"
fi
}
# More of the tmux workaround described above.
function print_st() {
if [[ $TERM == screen* ]] ; then
printf "\a\033\\"
else
printf "\a"
fi
}
# set_color key rgb
function set_color() {
print_osc
printf '1337;SetColors=%s=%s' "$1" "$2"
print_st
}
function error() {
echo "ERROR: $*" 1>&2
}
function show_help() {
if [ $open = 1 ]; then
print_st
fi
echo "Usage"
echo ""
echo "1) To set a specific color to an RGB value:"
echo " it2setcolor name color [name color...]" 1>& 2
echo "For example:"
echo " it2setcolor fg fff"
echo ""
echo "name is one of:"
echo " fg bg bold link selbg selfg curbg curfg underline tab"
echo " black red green yellow blue magenta cyan white"
echo " br_black br_red br_green br_yellow br_blue br_magenta br_cyan br_white"
echo ""
echo "color is of the format:"
echo " RGB (three hex digits, like fff)"
echo " RRGGBB (six hex digits, like f0f0f0)"
echo " cs:RGB (cs is a color space name)"
echo " cs:RRGGBB (cs is a color space name)"
echo ""
echo " The color space names accepted in the color are:"
echo " srgb (sRGB, the default if none is specified)"
echo " rgb (Apple's old device-independent colorspace)"
echo " p3 (Apple's fancy large-gamut colorspace)"
echo ""
echo "2) To switch to a named color preset:"
echo " it2setcolor preset name"
echo "For example:"
echo " it2setcolor preset 'Light Background'"
echo ""
echo "3) To reset the current tab's color to the system default:"
echo " it2setcolor tab default"
}
# Show help if no arguments and no stdin.
if [ $# -eq 0 ]; then
show_help
exit
fi
# Look for command line flags.
while [ $# -gt 0 ]; do
case "$1" in
-h|--h|--help)
show_help
exit
;;
-*)
error "Unknown option flag: $1"
show_help
exit 1
;;
*)
if [ $# -lt 2 ]; then
show_help
exit
fi
if [ $open = 0 ]; then
open=1
print_osc
printf '1337;SetColors='
else
printf ","
fi
# name is not checked for validity because we'd like this to work with future colors, too.
printf "%s=%s" "$1" "$2"
shift
;;
esac
shift
done
if [ $open = 1 ]; then
print_st
else
show_help
fi
exit 0

121
.iterm2/it2setkeylabel Executable file
View File

@@ -0,0 +1,121 @@
#!/bin/bash
# tmux requires unrecognized OSC sequences to be wrapped with DCS tmux;
# <sequence> ST, and for all ESCs in <sequence> to be replaced with ESC ESC. It
# only accepts ESC backslash for ST.
function print_osc() {
if [[ $TERM == screen* ]] ; then
printf "\033Ptmux;\033\033]"
else
printf "\033]"
fi
}
# More of the tmux workaround described above.
function print_st() {
if [[ $TERM == screen* ]] ; then
printf "\a\033\\"
else
printf "\a"
fi
}
function show_help() {
echo "Usage:" 1>& 2
echo " $(basename $0) set Fn Label" 1>& 2
echo " Where n is a value from 1 to 20" 1>& 2
echo " $(basename $0) push [name]" 1>& 2
echo " Saves the current labels with an optional name. Resets labels to their default value, unless name begins with a "." character." 1>& 2
echo " $(basename $0) pop [name]" 1>& 2
echo " If name is given, all key labels up to and including the one with the matching name are popped." 1>& 2
echo "" 1>& 2
echo "Example:" 1>& 2
echo "#!/bin/bash" 1>& 2
echo "# Wrapper script for mc that sets function key labels" 1>& 2
echo "NAME=mc_\$RANDOM" 1>& 2
echo "# Save existing labels" 1>& 2
echo "$(basename $0) push \$NAME" 1>& 2
echo "$(basename $0) set F1 Help" 1>& 2
echo "$(basename $0) set F2 Menu" 1>& 2
echo "$(basename $0) set F3 View" 1>& 2
echo "$(basename $0) set F4 Edit" 1>& 2
echo "$(basename $0) set F5 Copy" 1>& 2
echo "$(basename $0) set F6 Move" 1>& 2
echo "$(basename $0) set F7 Mkdir" 1>& 2
echo "$(basename $0) set F8 Del" 1>& 2
echo "$(basename $0) set F9 Menu" 1>& 2
echo "$(basename $0) set F10 Quit" 1>& 2
echo "$(basename $0) set F11 Menu" 1>& 2
echo "$(basename $0) set F13 View" 1>& 2
echo "$(basename $0) set F14 Edit" 1>& 2
echo "$(basename $0) set F15 Copy" 1>& 2
echo "$(basename $0) set F16 Move" 1>& 2
echo "$(basename $0) set F17 Find" 1>& 2
echo "mc" 1>& 2
echo "# Restore labels to their previous state" 1>& 2
echo "$(basename $0) pop \$NAME" 1>& 2
}
## Main
if [[ $# == 0 ]]
then
show_help
exit 1
fi
if [[ $1 == set ]]
then
if [[ $# != 3 ]]
then
show_help
exit 1
fi
print_osc
printf "1337;SetKeyLabel=%s=%s" "$2" "$3"
print_st
elif [[ $1 == push ]]
then
if [[ $# == 1 ]]
then
print_osc
printf "1337;PushKeyLabels"
print_st
elif [[ $# == 2 ]]
then
if [[ $2 == "" ]]
then
echo "Name must not be empty" 1>& 2
exit 1
fi
print_osc
printf "1337;PushKeyLabels=%s" "$2"
print_st
else
show_help
exit 1
fi
elif [[ $1 == pop ]]
then
if [[ $# == 1 ]]
then
print_osc
printf "1337;PopKeyLabels"
print_st
elif [[ $# == 2 ]]
then
if [[ $2 == "" ]]
then
echo "Name must not be empty" 1>& 2
exit 1
fi
print_osc
printf "1337;PopKeyLabels=%s" "$2"
print_st
else
show_help
exit 1
fi
else
show_help
exit 1
fi

98
.iterm2/it2ul Executable file
View File

@@ -0,0 +1,98 @@
#!/bin/bash
trap clean_up EXIT
_STTY=$(stty -g) ## Save current terminal setup
stty -echo ## Turn off echo
function clean_up() {
stty "$_STTY" ## Restore terminal settings
}
function show_help() {
echo "Usage: $(basename $0) [destination [tar flags]]" 1>& 2
echo " If given, the destination specifies the directory to place downloaded files."
echo " Further options are passed through to tar. See your system's manpage for tar for details."
}
function bad_input() {
echo "Bad input: %1" 1>& 2
exit 1
}
function die() {
echo "Fatal error: $1" 1>& 2
exit 1
}
function read_base64_stanza() {
value=""
while read line;
do
if [ "$line" == "" ]; then
break
fi
printf "%s" "$line"
done
}
function decode() {
VERSION=$(base64 --version 2>&1)
if [[ "$VERSION" =~ fourmilab ]]; then
BASE64ARG=-d
elif [[ "$VERSION" =~ GNU ]]; then
BASE64ARG=-di
else
BASE64ARG=-D
fi
base64 "$BASE64ARG" <<< "$1"
}
# tmux requires unrecognized OSC sequences to be wrapped with DCS tmux;
# <sequence> ST, and for all ESCs in <sequence> to be replaced with ESC ESC. It
# only accepts ESC backslash for ST.
function print_osc() {
if [[ $TERM == screen* ]] ; then
printf "\033Ptmux;\033\033]"
else
printf "\033]"
fi
}
# More of the tmux workaround described above.
function print_st() {
if [[ $TERM == screen* ]] ; then
printf "\a\033\\"
else
printf "\a"
fi
}
function send_request_for_upload() {
print_osc
printf '1337;RequestUpload=format=tgz' ""
print_st
}
location="$PWD"
if [[ $# > 0 ]]
then
location="$1"
shift
fi
send_request_for_upload
read status
if [[ $status == ok ]]
then
data=$(read_base64_stanza)
clean_up
decode "$data" | tar -x -z -C "$location" -f - $* 1>& 2
elif [[ $status == abort ]]
then
echo "Upload aborted" 1>& 2
else
die "Unknown status: $status" 1>& 2
fi

104
.iterm2/it2universion Executable file
View File

@@ -0,0 +1,104 @@
#!/bin/bash
# tmux requires unrecognized OSC sequences to be wrapped with DCS tmux;
# <sequence> ST, and for all ESCs in <sequence> to be replaced with ESC ESC. It
# only accepts ESC backslash for ST.
function print_osc() {
if [[ $TERM == screen* ]] ; then
printf "\033Ptmux;\033\033]"
else
printf "\033]"
fi
}
# More of the tmux workaround described above.
function print_st() {
if [[ $TERM == screen* ]] ; then
printf "\a\033\\"
else
printf "\a"
fi
}
function show_help() {
echo "Usage:" 1>& 2
echo " $(basename $0) set 8" 1>& 2
echo " $(basename $0) set 9" 1>& 2
echo " $(basename $0) push [name]" 1>& 2
echo " Saves the current version with an optional name." 1>& 2
echo " $(basename $0) pop [name]" 1>& 2
echo " If name is given, all versions up to and including the one with the matching name are popped." 1>& 2
}
function set_version() {
print_osc
printf "1337;UnicodeVersion=$1"
print_st
}
function push_version() {
print_osc
printf "1337;UnicodeVersion=push $1"
print_st
}
function pop_version() {
print_osc
printf "1337;UnicodeVersion=pop $1"
print_st
}
## Main
if [[ $# == 0 ]]
then
show_help
exit 1
fi
if [[ $1 == set ]]
then
if [[ $# != 2 ]]
then
show_help
exit 1
fi
set_version $2
elif [[ $1 == push ]]
then
if [[ $# == 1 ]]
then
push_version ""
elif [[ $# == 2 ]]
then
if [[ $2 == "" ]]
then
echo "Name must not be empty" 1>& 2
exit 1
fi
push_version "$2"
else
show_help
exit 1
fi
elif [[ $1 == pop ]]
then
if [[ $# == 1 ]]
then
pop_version ""
elif [[ $# == 2 ]]
then
if [[ $2 == "" ]]
then
echo "Name must not be empty" 1>& 2
exit 1
fi
pop_version "$2"
else
show_help
exit 1
fi
else
show_help
exit 1
fi

2
.zshrc
View File

@@ -69,3 +69,5 @@ setopt noincappendhistory
setopt nosharehistory setopt nosharehistory
. $HOME/.shellrc.load . $HOME/.shellrc.load
test -e "${HOME}/.iterm2_shell_integration.zsh" && source "${HOME}/.iterm2_shell_integration.zsh"