iTerm2 shell integration scripts offline usage
At times we are working in an internet less environment. So, here are a few things we can do,
- Make the scripts available over a local http server
- Change scripts for any http://internet-address/ to http://local-address
Making scripts availableĀ on local
$ python -mSimpleHTTPServer
Run the above command from the directory where the scripts are available after changes from step 2 (above)
It spins up a local http server that runs on port 8000
Changing scripts
Well, I changed references to all http location to point to https://www.robin.eu.orgname:8000/files
My iTerm2 scripts are below,
- bash_startup.in
- fish_startup.in
- imgcat
- install_shell_integration_and_utilities.sh
- it2dl
- tcsh_startup.in
- zsh_startup.in
bash_startup.in
#!/bin/bash
# This is based on "preexec.bash" but is customized for iTerm2.
# Note: this module requires 2 bash features which you must not otherwise be
# using: the "DEBUG" trap, and the "PROMPT_COMMAND" variable. iterm2_preexec_install
# will override these and if you override one or the other this _will_ break.
# This is known to support bash3, as well as *mostly* support bash2.05b. It
# has been tested with the default shells on MacOS X 10.4 "Tiger", Ubuntu 5.10
# "Breezy Badger", Ubuntu 6.06 "Dapper Drake", and Ubuntu 6.10 "Edgy Eft".
# tmux and screen are not supported; even using the tmux hack to get escape
# codes passed through, ncurses interferes and the cursor isn't in the right
# place at the time it's passed through.
if [[ "$TERM" != screen && "$ITERM_SHELL_INTEGRATION_INSTALLED" = "" && "$-" == *i* ]]; then
ITERM_SHELL_INTEGRATION_INSTALLED=Yes
# Saved copy of your PS1. This is used to detect if the user changes PS1
# directly. ITERM_PREV_PS1 will hold the last value that this script set PS1 to
# (including various custom escape sequences).
ITERM_PREV_PS1="$PS1"
# This variable describes whether we are currently in "interactive mode";
# i.e. whether this shell has just executed a prompt and is waiting for user
# input. It documents whether the current command invoked by the trace hook is
# run interactively by the user; it's set immediately after the prompt hook,
# and unset as soon as the trace hook is run.
ITERM_PREEXEC_INTERACTIVE_MODE=""
# Default do-nothing implementation of preexec.
function preexec () {
true
}
# Default do-nothing implementation of precmd.
function precmd () {
true
}
# This function is installed as the PROMPT_COMMAND; it is invoked before each
# interactive prompt display. It sets a variable to indicate that the prompt
# was just displayed, to allow the DEBUG trap, below, to know that the next
# command is likely interactive.
function iterm2_preexec_invoke_cmd () {
# Ideally we could do this in iterm2_preexec_install but CentOS 7.2 and
# RHEL 7.2 complain about bashdb-main.inc not existing if you do that
# (issue 4160).
# *BOTH* of these options need to be set for the DEBUG trap to be invoked
# in ( ) subshells. This smells like a bug in bash to me. The null stackederr
# redirections are to quiet errors on bash2.05 (i.e. OSX's default shell)
# where the options can't be set, and it's impossible to inherit the trap
# into subshells.
set -o functrace > /dev/null 2>&1
shopt -s extdebug > /dev/null 2>&1
\local s=$?
last_hist_ent="$(HISTTIMEFORMAT= builtin history 1)";
precmd;
# This is an iTerm2 addition to try to work around a problem in the
# original preexec.bash.
# When the PS1 has command substitutions, this gets invoked for each
# substitution and each command that's run within the substitution, which
# really adds up. It would be great if we could do something like this at
# the end of this script:
# PS1="$(iterm2_prompt_prefix)$PS1($iterm2_prompt_suffix)"
# and have iterm2_prompt_prefix set a global variable that tells precmd not to
# output anything and have iterm2_prompt_suffix reset that variable.
# Unfortunately, command substitutions run in subshells and can't
# communicate to the outside world.
# Instead, we have this workaround. We save the original value of PS1 in
# $ITERM_ORIG_PS1. Then each time this function is run (it's called from
# PROMPT_COMMAND just before the prompt is shown) it will change PS1 to a
# string without any command substitutions by doing eval on ITERM_ORIG_PS1. At
# this point ITERM_PREEXEC_INTERACTIVE_MODE is still the empty string, so preexec
# won't produce output for command substitutions.
# The first time this is called ITERM_ORIG_PS1 is unset. This tests if the variable
# is undefined (not just empty) and initializes it. We can't initialize this at the
# top of the script because it breaks with liquidprompt. liquidprompt wants to
# set PS1 from a PROMPT_COMMAND that runs just before us. Setting ITERM_ORIG_PS1
# at the top of the script will overwrite liquidprompt's PS1, whose value would
# never make it into ITERM_ORIG_PS1. Issue 4532. It's important to check
# if it's undefined before checking if it's empty because some users have
# bash set to error out on referencing an undefined variable.
if [ -z "${ITERM_ORIG_PS1+xxx}" ]
then
# ITERM_ORIG_PS1 always holds the last user-set value of PS1.
# You only get here on the first time iterm2_preexec_invoke_cmd is called.
export ITERM_ORIG_PS1="$PS1"
fi
if [[ "$PS1" != "$ITERM_PREV_PS1" ]]
then
export ITERM_ORIG_PS1="$PS1"
fi
# Get the value of the prompt prefix, which will change $?
\local iterm2_prompt_prefix_value="$(iterm2_prompt_prefix)"
# Reset $? to its saved value, which might be used in $ITERM_ORIG_PS1.
sh -c "exit $s"
# Set PS1 to various escape sequences, the user's preferred prompt, and more escape sequences.
export PS1="\[$iterm2_prompt_prefix_value\]$ITERM_ORIG_PS1\[$(iterm2_prompt_suffix)\]"
# Save the value we just set PS1 to so if the user changes PS1 we'll know and we can update ITERM_ORIG_PS1.
export ITERM_PREV_PS1="$PS1"
sh -c "exit $s"
# This must be the last line in this function, or else
# iterm2_preexec_invoke_exec will do its thing at the wrong time.
ITERM_PREEXEC_INTERACTIVE_MODE="yes";
}
# This function is installed as the DEBUG trap. It is invoked before each
# interactive prompt display. Its purpose is to inspect the current
# environment to attempt to detect if the current command is being invoked
# interactively, and invoke 'preexec' if so.
function iterm2_preexec_invoke_exec () {
if [ ! -t 1 ]
then
# We're in a piped subshell (STDOUT is not a TTY) like
# (echo -n A; sleep 1; echo -n B) | wc -c
# ...which should return "2".
return
fi
if [[ -n "${COMP_LINE:-}" ]]
then
# We're in the middle of a completer. This obviously can't be
# an interactively issued command.
return
fi
if [[ -z "$ITERM_PREEXEC_INTERACTIVE_MODE" ]]
then
# We're doing something related to displaying the prompt. Let the
# prompt set the title instead of me.
return
else
# If we're in a subshell, then the prompt won't be re-displayed to put
# us back into interactive mode, so let's not set the variable back.
# In other words, if you have a subshell like
# (sleep 1; sleep 2)
# You want to see the 'sleep 2' as a set_command_title as well.
if [[ 0 -eq "$BASH_SUBSHELL" ]]
then
ITERM_PREEXEC_INTERACTIVE_MODE=""
fi
fi
if [[ "iterm2_preexec_invoke_cmd" == "$BASH_COMMAND" ]]
then
# Sadly, there's no cleaner way to detect two prompts being displayed
# one after another. This makes it important that PROMPT_COMMAND
# remain set _exactly_ as below in iterm2_preexec_install. Let's switch back
# out of interactive mode and not trace any of the commands run in
# precmd.
# Given their buggy interaction between BASH_COMMAND and debug traps,
# versions of bash prior to 3.1 can't detect this at all.
ITERM_PREEXEC_INTERACTIVE_MODE=""
return
fi
# In more recent versions of bash, this could be set via the "BASH_COMMAND"
# variable, but using history here is better in some ways: for example, "ps
# auxf | less" will show up with both sides of the pipe if we use history,
# but only as "ps auxf" if not.
hist_ent="$(HISTTIMEFORMAT= builtin history 1)";
\local prev_hist_ent="${last_hist_ent}";
last_hist_ent="${hist_ent}";
if [[ "${prev_hist_ent}" != "${hist_ent}" ]]; then
\local this_command="$(echo "${hist_ent}" | sed -e "s/^[ ]*[0-9]*[ ]*//g")";
else
\local this_command="";
fi;
# If none of the previous checks have earlied out of this function, then
# the command is in fact interactive and we should invoke the user's
# preexec hook with the running command as an argument.
preexec "$this_command";
}
# Execute this to set up preexec and precmd execution.
function iterm2_preexec_install () {
# Finally, install the actual traps.
if ( [ x"${PROMPT_COMMAND:-}" = x ]); then
PROMPT_COMMAND="iterm2_preexec_invoke_cmd";
else
# If there's a trailing semicolon folowed by spaces, remove it (issue 3358).
PROMPT_COMMAND="$(echo -n $PROMPT_COMMAND | sed -e 's/; *$//'); iterm2_preexec_invoke_cmd";
fi
# The $_ is ignored, but prevents it from changing (issue 3932).
trap 'iterm2_preexec_invoke_exec "$_"' DEBUG;
}
# -- begin iTerm2 customization
function iterm2_begin_osc {
printf "\033]"
}
function iterm2_end_osc {
printf "\007"
}
# Runs after interactively edited command but before execution
function preexec() {
iterm2_begin_osc
printf "133;C;"
iterm2_end_osc
# If PS1 still has the value we set it to in iterm2_preexec_invoke_cmd then
# restore it to its original value. It might have changed if you have
# another PROMPT_COMMAND (like liquidprompt) that modifies PS1.
if [ -n "${ITERM_ORIG_PS1+xxx}" -a "$PS1" = "$ITERM_PREV_PS1" ]
then
export PS1="$ITERM_ORIG_PS1"
fi
iterm2_ran_preexec="yes"
}
function precmd () {
# Work around a bug in CentOS 7.2 where preexec doesn't run if you press
# ^C while entering a command.
if [[ -z "${iterm2_ran_preexec:-}" ]]
then
preexec ""
fi
iterm2_ran_preexec=""
}
function iterm2_print_state_data() {
iterm2_begin_osc
printf "1337;RemoteHost=%s@%s" "$USER" "$iterm2_hostname"
iterm2_end_osc
iterm2_begin_osc
printf "1337;CurrentDir=%s" "$PWD"
iterm2_end_osc
iterm2_print_user_vars
}
# Usage: iterm2_set_user_var key value
function iterm2_set_user_var() {
iterm2_begin_osc
printf "1337;SetUserVar=%s=%s" "$1" $(printf "%s" "$2" | base64)
iterm2_end_osc
}
if [ -z "$(type -t iterm2_print_user_vars)" ] || [ "$(type -t iterm2_print_user_vars)" != function ]; then
# iterm2_print_user_vars is not already defined. Provide a no-op default version.
#
# Users can write their own version of this function. It should call
# iterm2_set_user_var but not produce any other output.
function iterm2_print_user_vars() {
true
}
fi
function iterm2_prompt_prefix() {
iterm2_begin_osc
printf "133;D;\$?"
iterm2_end_osc
iterm2_print_state_data
iterm2_begin_osc
printf "133;A"
iterm2_end_osc
}
function iterm2_prompt_suffix() {
iterm2_begin_osc
printf "133;B"
iterm2_end_osc
}
function iterm2_print_version_number() {
iterm2_begin_osc
printf "1337;ShellIntegrationVersion=2;shell=bash"
iterm2_end_osc
}
# If hostname -f is slow on your system, set iterm2_hostname before sourcing this script.
if [ -z "${iterm2_hostname:-}" ]; then
iterm2_hostname=$(hostname -f)
fi
iterm2_preexec_install
# This is necessary so the first command line will have a hostname and current directory.
iterm2_print_state_data
iterm2_print_version_number
fi
fish_startup.in
if begin; status --is-interactive; and not functions -q -- iterm2_status; and [ "$TERM" != screen ]; end
function iterm2_status
printf "\033]133;D;%s\007" $argv
end
# Mark start of prompt
function iterm2_prompt_start
printf "\033]133;A\007"
end
# Mark end of prompt
function iterm2_prompt_end
printf "\033]133;B\007"
end
# Tell terminal to create a mark at this location
function iterm2_preexec
# For other shells we would output status here but we can't do that in fish.
printf "\033]133;C;\007"
end
# Usage: iterm2_set_user_var key value
# These variables show up in badges (and later in other places). For example
# iterm2_set_user_var currentDirectory "$PWD"
# Gives a variable accessible in a badge by \(user.currentDirectory)
# Calls to this go in iterm2_print_user_vars.
function iterm2_set_user_var
printf "\033]1337;SetUserVar=%s=%s\007" "$argv[1]" (printf "%s" "$argv[2]" | base64)
end
# iTerm2 inform terminal that command starts here
function iterm2_precmd
printf "\033]1337;RemoteHost=%s@%s\007\033]1337;CurrentDir=$PWD\007" $USER $iterm2_hostname
# Users can define a function called iterm2_print_user_vars.
# It should call iterm2_set_user_var and produce no other output.
if functions -q -- iterm2_print_user_vars
iterm2_print_user_vars
end
end
functions -c fish_prompt iterm2_fish_prompt
if functions -q -- fish_mode_prompt
# This path for fish 2.2. Works nicer with fish_vi_mode.
functions -c fish_mode_prompt iterm2_fish_mode_prompt
function fish_mode_prompt --description 'Write out the mode prompt; do not replace this. Instead, change fish_mode_prompt before sourcing .iterm2_shell_integration.fish, or modify iterm2_fish_mode_prompt instead.'
set -l last_status $status
iterm2_status $last_status
iterm2_prompt_start
sh -c "exit $last_status"
iterm2_fish_mode_prompt
end
function fish_prompt --description 'Write out the prompt; do not replace this. Instead, change fish_prompt before sourcing .iterm2_shell_integration.fish, or modify iterm2_fish_prompt instead.'
# Remove the trailing newline from the original prompt. Storing a
# command's output to a variable loses all the newlines, causing the
# prompt's lines to get joined together. You also can't pass it to a
# shell command command. So we can only use it in something like a for
# loop.
for line in (iterm2_fish_prompt)
set -q last_line; and echo $last_line
set last_line $line
end
set -q last_line; and echo -n $last_line
iterm2_prompt_end
end
else
# Pre-2.2 path
function fish_prompt --description 'Write out the prompt; do not replace this. Instead, change fish_prompt before sourcing .iterm2_shell_integration.fish, or modify iterm2_fish_prompt instead.'
# Save our status
set -l last_status $status
iterm2_status $last_status
iterm2_prompt_start
# Restore the status
sh -c "exit $last_status"
iterm2_fish_prompt
iterm2_prompt_end
end
end
function -v _ underscore_change
if [ x$_ = xfish ]
iterm2_precmd
else
iterm2_preexec
end
end
# If hostname -f is slow for you, set iterm2_hostname before sourcing this script
if not set -q iterm2_hostname
set iterm2_hostname (hostname -f)
end
iterm2_precmd
printf "\033]1337;ShellIntegrationVersion=2;shell=fish\007"
end
imgcat
#!/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
# filename: Filename to convey to client
# inline: 0 or 1
# base64contents: Base64-encoded contents
function print_image() {
print_osc
printf '1337;File='
if [[ -n "$1" ]]; then
printf 'name='`echo -n "$1" | base64`";"
fi
if $(base64 --version 2>&1 | grep GNU > /dev/null)
then
BASE64ARG=-d
else
BASE64ARG=-D
fi
echo -n "$3" | base64 $BASE64ARG | wc -c | awk '{printf "size=%d",$1}'
printf ";inline=$2"
printf ":"
echo -n "$3"
print_st
printf '\n'
}
function error() {
echo "ERROR: $*" 1>&2
}
function show_help() {
echo "Usage: imgcat 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
;;
-*)
error "Unknown option flag: $1"
show_help
exit 1
;;
*)
if [ -r "$1" ] ; then
print_image "$1" 1 "$(base64 < "$1")"
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
install_shell_integration_and_utilities.sh
#!/bin/bash
function die() {
echo "${1}"
exit 1
}
which printf > /dev/null 2>&1 || die "Shell integration requires the printf binary to be in your path."
SHELL=$(echo "${SHELL}" | tr / "\n" | tail -1)
URL=""
HOME_PREFIX='${HOME}'
SHELL_AND='&&'
QUOTE=''
if [ "${SHELL}" == tcsh ]
then
URL="http://10.0.2.2:8000/tcsh_startup.in"
SCRIPT="${HOME}/.login"
QUOTE='"'
ALIASES='alias imgcat ~/.iterm2/imgcat; alias it2dl ~/.iterm2/it2dl'
fi
if [ "${SHELL}" == zsh ]
then
URL="http://10.0.2.2:8000/zsh_startup.in"
SCRIPT="${HOME}/.zshrc"
QUOTE='"'
ALIASES='alias imgcat=~/.iterm2/imgcat; alias it2dl=~/.iterm2/it2dl'
fi
if [ "${SHELL}" == bash ]
then
URL="http://10.0.2.2:8000/bash_startup.in"
test -f "${HOME}/.bash_profile" && SCRIPT="${HOME}/.bash_profile" || SCRIPT="${HOME}/.profile"
QUOTE='"'
ALIASES='alias imgcat=~/.iterm2/imgcat; alias it2dl=~/.iterm2/it2dl'
fi
if [ `basename "${SHELL}"` == fish ]
then
echo "Make sure you have fish 2.2 or later. Your version is:"
fish -v
URL="http://10.0.2.2:8000/fish_startup.in"
mkdir -p "${HOME}/.config/fish"
SCRIPT="${HOME}/.config/fish/config.fish"
HOME_PREFIX='{$HOME}'
SHELL_AND='; and'
ALIASES='alias imgcat=~/.iterm2/imgcat; alias it2dl=~/.iterm2/it2dl'
fi
if [ "${URL}" == "" ]
then
die "Your shell, ${SHELL}, is not supported yet. Only tcsh, zsh, bash, and fish are supported. Sorry!"
exit 1
fi
FILENAME="${HOME}/.iterm2_shell_integration.${SHELL}"
RELATIVE_FILENAME="${HOME_PREFIX}/.iterm2_shell_integration.${SHELL}"
echo "Downloading script from ${URL} and saving it to ${FILENAME}..."
curl -L "${URL}" > "${FILENAME}" || die "Couldn't download script from ${URL}"
chmod +x "${FILENAME}"
echo "Checking if ${SCRIPT} contains iterm2_shell_integration..."
grep iterm2_shell_integration "${SCRIPT}" > /dev/null 2>&1 || (echo "Appending source command to ${SCRIPT}..."; echo "" >> "${SCRIPT}"; echo "test -e ${QUOTE}${RELATIVE_FILENAME}${QUOTE} ${SHELL_AND} source ${QUOTE}${RELATIVE_FILENAME}${QUOTE}" >> "${SCRIPT}")
test -d ~/.iterm2 || mkdir ~/.iterm2
echo "Downloading imgcat..."
curl -L "http://10.0.2.2:8000/imgcat" > ~/.iterm2/imgcat && chmod +x ~/.iterm2/imgcat
echo "Downloading it2dl..."
curl -L "http://10.0.2.2:8000/it2dl" > ~/.iterm2/it2dl && chmod +x ~/.iterm2/it2dl
echo "Adding aliases..."
echo "$ALIASES" >> "${FILENAME}"
echo "Done."
echo "--------------------------------------------------------------------------------"
echo ""
echo "The next time you log in, shell integration will be enabled."
echo ""
echo "You will also have these commands:"
echo "imgcat filename"
echo " Displays the image inline."
echo "it2dl filename"
echo " Downloads the specified file, saving it in your Downloads folder."
it2dl
#!/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
tcsh_startup.in
# Note that tcsh doesn't allow the prompt to end in an escape code so the terminal space here is required. iTerm2 ignores spaces after this code.
# This is the second version of this script. It rejects "screen" terminals and uses aliases to make the code readable.
# Prevent the script from running twice.
if ( ! ($?iterm2_shell_integration_installed)) then
# Make sure this is a login shell.
if ( $?loginsh) then
# Define aliases for the start and end of OSC escape codes used by shell integration.
if ( x"$TERM" != xscreen ) then
# If hostname -f is slow to run on your system, set iterm2_hostname before sourcing this script.
if ( ! ($?iterm2_hostname)) then
set iterm2_hostname=`hostname -f`
endif
set iterm2_shell_integration_installed="yes"
alias _iterm2_start 'printf "\033]"'
alias _iterm2_end 'printf "\007"'
alias _iterm2_end_prompt 'printf "\007"'
# Define aliases for printing the current hostname
alias _iterm2_print_remote_host 'printf "1337;RemoteHost=%s@%s" "$USER" "$iterm2_hostname"'
alias _iterm2_remote_host "(_iterm2_start; _iterm2_print_remote_host; _iterm2_end)"
# Define aliases for printing the current directory
alias _iterm2_print_current_dir 'printf "1337;CurrentDir=$PWD"'
alias _iterm2_current_dir "(_iterm2_start; _iterm2_print_current_dir; _iterm2_end)"
# Define aliases for printing the shell integration version this script is written against
alias _iterm2_print_shell_integration_version 'printf "1337;ShellIntegrationVersion=2;shell=tcsh"'
alias _iterm2_shell_integration_version "(_iterm2_start; _iterm2_print_shell_integration_version; _iterm2_end)"
# Define aliases for defining the boundary between a command prompt and the
# output of a command started from that prompt.
alias _iterm2_print_between_prompt_and_exec 'printf "133;C;"'
alias _iterm2_between_prompt_and_exec "(_iterm2_start; _iterm2_print_between_prompt_and_exec; _iterm2_end)"
# Define aliases for defining the start of a command prompt.
alias _iterm2_print_before_prompt 'printf "133;A"'
alias _iterm2_before_prompt "(_iterm2_start; _iterm2_print_before_prompt; _iterm2_end_prompt)"
# Define aliases for defining the end of a command prompt.
alias _iterm2_print_after_prompt 'printf "133;B"'
alias _iterm2_after_prompt "(_iterm2_start; _iterm2_print_after_prompt; _iterm2_end_prompt)"
# Define aliases for printing the status of the last command.
alias _iterm2_last_status 'printf "\033]133;D;$?\007"'
# Usage: iterm2_set_user_var key `printf "%s" value | base64`
alias iterm2_set_user_var 'printf "\033]1337;SetUserVar=%s=%s\007"'
# User may override this to set user-defined vars. It should look like this, because your shell is terrible for scripting:
# alias _iterm2_user_defined_vars (iterm2_set_user_var key1 `printf "%s" value1 | base64`; iterm2_set_user_var key2 `printf "%s" value2 | base64`; ...)
(which _iterm2_user_defined_vars >& /dev/null) || alias _iterm2_user_defined_vars ''
# Combines all status update aliases
alias _iterm2_update_current_state '_iterm2_remote_host; _iterm2_current_dir; _iterm2_user_defined_vars'
# This is necessary so the first command line will have a hostname and current directory.
_iterm2_update_current_state
_iterm2_shell_integration_version
# Define precmd, which runs just before the prompt is printed. This could go
# in $prompt but this keeps things a little simpler in here.
# No parens or iterm2_start call is allowed prior to evaluating the last status.
alias precmd '_iterm2_last_status; _iterm2_update_current_state'
# Define postcmd, which runs just before a command is executed.
alias postcmd '(_iterm2_between_prompt_and_exec)'
# Quotes are ignored inside backticks, so use noglob to prevent bug 3393.
set noglob
# Remove the terminal space from the prompt to work around a tcsh bug.
set _iterm2_truncated_prompt=`echo "$prompt" | sed -e 's/ $//'`
# Wrap the prompt in FinalTerm escape codes and re-add a terminal space.
set prompt="%{"`_iterm2_before_prompt`"%}$_iterm2_truncated_prompt%{"`_iterm2_after_prompt`"%} "
# Turn globbing back on.
unset noglob
endif
endif
endif
zsh_startup.in
if [[ -o login ]]; then
if [ "$TERM" != "screen" -a "$ITERM_SHELL_INTEGRATION_INSTALLED" = "" ]; then
export ITERM_SHELL_INTEGRATION_INSTALLED=Yes
ITERM2_SHOULD_DECORATE_PROMPT="1"
# Indicates start of command output. Runs just before command executes.
iterm2_before_cmd_executes() {
printf "\033]133;C;\007"
}
iterm2_set_user_var() {
printf "\033]1337;SetUserVar=%s=%s\007" "$1" $(printf "%s" "$2" | base64)
}
# Users can write their own version of this method. It should call
# iterm2_set_user_var but not produce any other output.
# e.g., iterm2_set_user_var currentDirectory $PWD
# Accessible in iTerm2 (in a badge now, elsewhere in the future) as
# \(user.currentDirectory).
whence -v iterm2_print_user_vars > /dev/null 2>&1
if [ $? -ne 0 ]; then
iterm2_print_user_vars() {
}
fi
iterm2_print_state_data() {
printf "\033]1337;RemoteHost=%s@%s\007" "$USER" "$iterm2_hostname"
printf "\033]1337;CurrentDir=%s\007" "$PWD"
iterm2_print_user_vars
}
# Report return code of command; runs after command finishes but before prompt
iterm2_after_cmd_executes() {
printf "\033]133;D;%s\007" "$STATUS"
iterm2_print_state_data
}
# Mark start of prompt
iterm2_prompt_start() {
printf "\033]133;A\007"
}
# Mark end of prompt
iterm2_prompt_end() {
printf "\033]133;B\007"
}
# There are three possible paths in life.
#
# 1) A command is entered at the prompt and you press return.
# The following steps happen:
# * iterm2_preexec is invoked
# * PS1 is set to ITERM2_PRECMD_PS1
# * ITERM2_SHOULD_DECORATE_PROMPT is set to 1
# * The command executes (possibly reading or modifying PS1)
# * iterm2_precmd is invoked
# * ITERM2_PRECMD_PS1 is set to PS1 (as modified by command execution)
# * PS1 gets our escape sequences added to it
# * zsh displays your prompt
# * You start entering a command
#
# 2) You press ^C while entering a command at the prompt.
# The following steps happen:
# * (iterm2_preexec is NOT invoked)
# * iterm2_precmd is invoked
# * iterm2_before_cmd_executes is called since we detected that iterm2_preexec was not run
# * (ITERM2_PRECMD_PS1 and PS1 are not messed with, since PS1 already has our escape
# sequences and ITERM2_PRECMD_PS1 already has PS1's original value)
# * zsh displays your prompt
# * You start entering a command
#
# 3) A new shell is born.
# * PS1 has some initial value, either zsh's default or a value set before this script is sourced.
# * iterm2_precmd is invoked
# * ITERM2_SHOULD_DECORATE_PROMPT is initialized to 1
# * ITERM2_PRECMD_PS1 is set to the initial value of PS1
# * PS1 gets our escape sequences added to it
# * Your prompt is shown and you may begin entering a command.
#
# Invariants:
# * ITERM2_SHOULD_DECORATE_PROMPT is 1 during and just after command execution, and "" while the prompt is
# shown and until you enter a command and press return.
# * PS1 does not have our escape sequences during command execution
# * After the command executes but before a new one begins, PS1 has escape sequences and
# ITERM2_PRECMD_PS1 has PS1's original value.
iterm2_decorate_prompt() {
# This should be a raw PS1 without iTerm2's stuff. It could be changed during command
# execution.
ITERM2_PRECMD_PS1="$PS1"
ITERM2_SHOULD_DECORATE_PROMPT=""
# Add our escape sequences just before the prompt is shown.
PS1="%{$(iterm2_prompt_start)%}$PS1%{$(iterm2_prompt_end)%}"
}
iterm2_precmd() {
local STATUS="$?"
if [ -z "$ITERM2_SHOULD_DECORATE_PROMPT" ]; then
# You pressed ^C while entering a command (iterm2_preexec did not run)
iterm2_before_cmd_executes
fi
iterm2_after_cmd_executes "$STATUS"
if [ -n "$ITERM2_SHOULD_DECORATE_PROMPT" ]; then
iterm2_decorate_prompt
fi
}
# This is not run if you press ^C while entering a command.
iterm2_preexec() {
# Set PS1 back to its raw value prior to executing the command.
PS1="$ITERM2_PRECMD_PS1"
ITERM2_SHOULD_DECORATE_PROMPT="1"
iterm2_before_cmd_executes
}
# If hostname -f is slow on your system, set iterm2_hostname prior to sourcing this script.
[[ -z "$iterm2_hostname" ]] && iterm2_hostname=`hostname -f`
[[ -z $precmd_functions ]] && precmd_functions=()
precmd_functions=($precmd_functions iterm2_precmd)
[[ -z $preexec_functions ]] && preexec_functions=()
preexec_functions=($preexec_functions iterm2_preexec)
iterm2_print_state_data
printf "\033]1337;ShellIntegrationVersion=2;shell=zsh\007"
fi
fi