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