Ottomata has uploaded a new change for review. https://gerrit.wikimedia.org/r/290934
Change subject: Update otto's iterm2 shell integration script ...................................................................... Update otto's iterm2 shell integration script Change-Id: Iffe9064020264cdb0c7d6869980d95450790321a --- M modules/admin/files/home/otto/.iterm2_shell_integration.bash 1 file changed, 92 insertions(+), 60 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/operations/puppet refs/changes/34/290934/1 diff --git a/modules/admin/files/home/otto/.iterm2_shell_integration.bash b/modules/admin/files/home/otto/.iterm2_shell_integration.bash index 4f2f2f6..21f0a0d 100755 --- a/modules/admin/files/home/otto/.iterm2_shell_integration.bash +++ b/modules/admin/files/home/otto/.iterm2_shell_integration.bash @@ -9,27 +9,23 @@ # 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". - -# Copy screen-run variables from the remote host, if they're available. - -# Saved copy of your PS1. This is used to detect if the user changes PS1 -# directly. prev_ps1 will hold the last value that this script set PS1 to -# (including various custom escape sequences). orig_ps1 always holds the last -# user-set value of PS1. -orig_ps1="$PS1" -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. -preexec_interactive_mode="" - # 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 ( [ x"$TERM" != xscreen ] ); then +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 @@ -45,8 +41,19 @@ # was just displayed, to allow the DEBUG trap, below, to know that the next # command is likely interactive. function iterm2_preexec_invoke_cmd () { - local s=$? - last_hist_ent="$(history 1)"; + # 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. @@ -60,33 +67,48 @@ # 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 - # $orig_ps1. Then each time this function is run (it's called from + # $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 orig_ps1. At - # this point preexec_interactive_mode is still the empty string, so preexec + # 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. - if [[ "$PS1" != "$prev_ps1" ]] + # 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 - export orig_ps1="$PS1" + # 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)" + \local iterm2_prompt_prefix_value="$(iterm2_prompt_prefix)" - # Reset $? to its saved value, which might be used in $orig_ps1. + # 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\]$orig_ps1\[$(iterm2_prompt_suffix)\]" + 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 orig_ps1. - export prev_ps1="$PS1" + # 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. - preexec_interactive_mode="yes"; + ITERM_PREEXEC_INTERACTIVE_MODE="yes"; } # This function is installed as the DEBUG trap. It is invoked before each @@ -101,13 +123,13 @@ # ...which should return "2". return fi - if [[ -n "$COMP_LINE" ]] + 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 "$preexec_interactive_mode" ]] + 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. @@ -120,7 +142,7 @@ # You want to see the 'sleep 2' as a set_command_title as well. if [[ 0 -eq "$BASH_SUBSHELL" ]] then - preexec_interactive_mode="" + ITERM_PREEXEC_INTERACTIVE_MODE="" fi fi if [[ "iterm2_preexec_invoke_cmd" == "$BASH_COMMAND" ]] @@ -133,7 +155,7 @@ # Given their buggy interaction between BASH_COMMAND and debug traps, # versions of bash prior to 3.1 can't detect this at all. - preexec_interactive_mode="" + ITERM_PREEXEC_INTERACTIVE_MODE="" return fi @@ -141,13 +163,13 @@ # 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="$(history 1)"; - local prev_hist_ent="${last_hist_ent}"; + 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")"; + \local this_command="$(echo "${hist_ent}" | sed -e "s/^[ ]*[0-9]*[ ]*//g")"; else - local this_command=""; + \local this_command=""; fi; # If none of the previous checks have earlied out of this function, then @@ -158,18 +180,8 @@ # Execute this to set up preexec and precmd execution. function iterm2_preexec_install () { - - # *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 - # Finally, install the actual traps. - if ( [ x"$PROMPT_COMMAND" = x ]); then + 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). @@ -192,10 +204,26 @@ # Runs after interactively edited command but before execution function preexec() { iterm2_begin_osc - printf "133;C;\r" + printf "133;C;" iterm2_end_osc - # Reset PS1 back to its original value so scripts can change it. - export PS1="$orig_ps1" + # 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() { @@ -217,11 +245,15 @@ iterm2_end_osc } - # Users can write their own version of this method. It should call - # iterm2_set_user_var but not produce any other output. - function iterm2_print_user_vars() { - true - } + 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 @@ -243,13 +275,13 @@ function iterm2_print_version_number() { iterm2_begin_osc - printf "1337;ShellIntegrationVersion=1" + 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 + if [ -z "${iterm2_hostname:-}" ]; then iterm2_hostname=$(hostname -f) fi iterm2_preexec_install -- To view, visit https://gerrit.wikimedia.org/r/290934 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Iffe9064020264cdb0c7d6869980d95450790321a Gerrit-PatchSet: 1 Gerrit-Project: operations/puppet Gerrit-Branch: production Gerrit-Owner: Ottomata <o...@wikimedia.org> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits