From d6492264c7541d41afcf2958142475ca1c7f7d3d Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 8 Jul 2022 18:55:04 +0530 Subject: [PATCH] Bash integration: Fix declare not creating global variables in .bashrc Fixes #5254 --- docs/changelog.rst | 2 + kitty_tests/shell_integration.py | 4 ++ shell-integration/bash/kitty.bash | 93 ++++++++++++++++--------------- 3 files changed, 53 insertions(+), 46 deletions(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index 2cc0940ff..c0f0e1a5c 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -65,6 +65,8 @@ Detailed list of changes - ssh kitten: A new option :code:`--symlink-strategy` to control how symlinks are copied to the remote machine (:iss:`5249`) +- Bash integration: Fix declare not creating global variables in .bashrc (:iss:`5254`) + 0.25.2 [2022-06-07] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/kitty_tests/shell_integration.py b/kitty_tests/shell_integration.py index 561b818b9..b0c803aa8 100644 --- a/kitty_tests/shell_integration.py +++ b/kitty_tests/shell_integration.py @@ -285,6 +285,10 @@ PS1="{ps1}" pty.write_to_child('\x04') pty.send_cmd_to_child('clear') pty.wait_till(lambda: pty.callbacks.titlebuf) + with self.run_shell(shell='bash', rc=f'''PS1="{ps1}"\ndeclare LOCAL_KSI_VAR=1''') as pty: + pty.callbacks.clear() + pty.send_cmd_to_child('declare') + pty.wait_till(lambda: 'LOCAL_KSI_VAR' in pty.screen_contents()) with self.run_shell(shell='bash', rc=f'''PS1="{ps1}"''') as pty: pty.callbacks.clear() pty.send_cmd_to_child('printf "%s\x16\a%s" "a" "b"') diff --git a/shell-integration/bash/kitty.bash b/shell-integration/bash/kitty.bash index 4a06ff6e0..5360518cb 100644 --- a/shell-integration/bash/kitty.bash +++ b/shell-integration/bash/kitty.bash @@ -3,59 +3,60 @@ if [[ "$-" != *i* ]] ; then builtin return; fi # check in interactive mode if [[ -z "$KITTY_SHELL_INTEGRATION" ]]; then builtin return; fi -_ksi_inject() { - # Load the normal bash startup files - if [[ -n "$KITTY_BASH_INJECT" ]]; then - builtin local kitty_bash_inject="$KITTY_BASH_INJECT" - builtin local ksi_val="$KITTY_SHELL_INTEGRATION" - builtin unset KITTY_SHELL_INTEGRATION # ensure manual sourcing of this file in bashrc does not have any effect - builtin unset KITTY_BASH_INJECT ENV - if [[ -z "$HOME" ]]; then HOME=~; fi - if [[ -z "$KITTY_BASH_ETC_LOCATION" ]]; then KITTY_BASH_ETC_LOCATION="/etc"; fi +# Load the normal bash startup files +if [[ -n "$KITTY_BASH_INJECT" ]]; then + builtin declare kitty_bash_inject="$KITTY_BASH_INJECT" + builtin declare ksi_val="$KITTY_SHELL_INTEGRATION" + builtin unset KITTY_SHELL_INTEGRATION # ensure manual sourcing of this file in bashrc does not have any effect + builtin unset KITTY_BASH_INJECT ENV + if [[ -z "$HOME" ]]; then HOME=~; fi + if [[ -z "$KITTY_BASH_ETC_LOCATION" ]]; then KITTY_BASH_ETC_LOCATION="/etc"; fi - _ksi_safe_source() { - if [[ -f "$1" && -r "$1" ]]; then - builtin source "$1" - builtin return 0 - fi - builtin return 1 + _ksi_sourceable() { + [[ -f "$1" && -r "$1" ]] && return 0; return 1; + } + + if [[ "$kitty_bash_inject" == *"posix"* ]]; then + _ksi_sourceable "$KITTY_BASH_POSIX_ENV" && { + builtin source "$KITTY_BASH_POSIX_ENV" + builtin export ENV="$KITTY_BASH_POSIX_ENV" } + else + builtin set +o posix + if [[ -n "$KITTY_BASH_UNEXPORT_HISTFILE" ]]; then + builtin export -n HISTFILE + builtin unset KITTY_BASH_UNEXPORT_HISTFILE + fi - if [[ "$kitty_bash_inject" == *"posix"* ]]; then - _ksi_safe_source "$KITTY_BASH_POSIX_ENV" && builtin export ENV="$KITTY_BASH_POSIX_ENV" - else - builtin set +o posix - if [[ -n "$KITTY_BASH_UNEXPORT_HISTFILE" ]]; then - builtin export -n HISTFILE - builtin unset KITTY_BASH_UNEXPORT_HISTFILE + # See run_startup_files() in shell.c in the Bash source code + if builtin shopt -q login_shell; then + if [[ "$kitty_bash_inject" != *"no-profile"* ]]; then + _ksi_sourceable "$KITTY_BASH_ETC_LOCATION/profile" && builtin source "$KITTY_BASH_ETC_LOCATION/profile" + for _ksi_i in "$HOME/.bash_profile" "$HOME/.bash_login" "$HOME/.profile"; do + _ksi_sourceable "$_ksi_i" && { builtin source "$_ksi_i"; break; } + done fi - - # See run_startup_files() in shell.c in the Bash source code - if builtin shopt -q login_shell; then - if [[ "$kitty_bash_inject" != *"no-profile"* ]]; then - _ksi_safe_source "$KITTY_BASH_ETC_LOCATION/profile" - _ksi_safe_source "$HOME/.bash_profile" || _ksi_safe_source "$HOME/.bash_login" || _ksi_safe_source "$HOME/.profile" - fi - else - if [[ "$kitty_bash_inject" != *"no-rc"* ]]; then - # Linux distros build bash with -DSYS_BASHRC. Unfortunately, there is - # no way to to probe bash for it and different distros use different files - # Arch, Debian, Ubuntu use /etc/bash.bashrc - # Fedora uses /etc/bashrc sourced from ~/.bashrc instead of SYS_BASHRC - # Void Linux uses /etc/bash/bashrc - _ksi_safe_source "$KITTY_BASH_ETC_LOCATION/bash.bashrc" || _ksi_safe_source "$KITTY_BASH_ETC_LOCATION/bash/bashrc" - if [[ -z "$KITTY_BASH_RCFILE" ]]; then KITTY_BASH_RCFILE="$HOME/.bashrc"; fi - _ksi_safe_source "$KITTY_BASH_RCFILE" - fi + else + if [[ "$kitty_bash_inject" != *"no-rc"* ]]; then + # Linux distros build bash with -DSYS_BASHRC. Unfortunately, there is + # no way to to probe bash for it and different distros use different files + # Arch, Debian, Ubuntu use /etc/bash.bashrc + # Fedora uses /etc/bashrc sourced from ~/.bashrc instead of SYS_BASHRC + # Void Linux uses /etc/bash/bashrc + for _ksi_i in "$KITTY_BASH_ETC_LOCATION/bash.bashrc" "$KITTY_BASH_ETC_LOCATION/bash/bashrc" ; do + _ksi_sourceable "$_ksi_i" && { builtin source "$_ksi_i"; break; } + done + if [[ -z "$KITTY_BASH_RCFILE" ]]; then KITTY_BASH_RCFILE="$HOME/.bashrc"; fi + _ksi_sourceable "$KITTY_BASH_RCFILE" && builtin source "$KITTY_BASH_RCFILE" fi fi - builtin unset KITTY_BASH_RCFILE KITTY_BASH_POSIX_ENV KITTY_BASH_ETC_LOCATION - builtin unset -f _ksi_safe_source - builtin export KITTY_SHELL_INTEGRATION="$ksi_val" fi -} -_ksi_inject -builtin unset -f _ksi_inject + builtin unset KITTY_BASH_RCFILE KITTY_BASH_POSIX_ENV KITTY_BASH_ETC_LOCATION + builtin unset -f _ksi_sourceable + builtin export KITTY_SHELL_INTEGRATION="$ksi_val" + builtin unset _ksi_i ksi_val kitty_bash_inject +fi + if [ "${BASH_VERSINFO:-0}" -lt 4 ]; then builtin unset KITTY_SHELL_INTEGRATION