akinomyoga / ble.sh

Bash Line Editor―a line editor written in pure Bash with syntax highlighting, auto suggestions, vim modes, etc. for Bash interactive sessions.
BSD 3-Clause "New" or "Revised" License
2.33k stars 77 forks source link

[0.3 & foot] [ranger] ctrl + A prints escape codes in fish and weechat if launched through ble.sh session #401

Closed ragnarov closed 4 months ago

ragnarov commented 5 months ago

ble version: 0.3.4+566651e bash version: 5.2.21(1)-release (x86_64-unknown-linux-musl) distro: void linux

after launching terminal (foot), and then starting fish, if I use ctrl+A or ctrl+E or shift+I, escape codes are printed, using foot terminal. I faced similar problems trying to use weechat. for ctrl+A I get [27;5;97~ for ctrl+E I get [27;5;101~ for shift+I I get [27;2;73~ for ctrl+U I get [27;5;117~ If I type reset in bash session and then launch fish, this don't happen using foot terminal. If I type reset in fishsession and then quit to bash using ctrl+d and then launch fish again from the same bash session, this problem don't happen using foot terminal. If I type reset in bash session, and then start weechat, I don't face any problem. Everything works normally. This problem don't happen in xterm at all.

my bashrc is given below. despite what it looks like, I used this exact bashrc to make sure the problem is not with whatever I am doing in the middle. But I am not sure.

## ble.sh
[[ $- == *i* ]] && source '/usr/share/blesh/ble.sh' --attach=none

###### Read and load ~/.rc if it exists
####v_shrc="${HOME}/.config/shell/rc"
####[ -f "${v_shrc}" ] && . "${v_shrc}" || echo "rc file not found!"
####
###### If not running interactively, don't do anything below
####
####[[ $- != *i* ]] && return
####
####
####
######----------------------------- Important Calls --------------------------------
####
####if [ -f '/usr/share/bash-completion/bash_completion' ]; then
####    source '/usr/share/bash-completion/bash_completion'
####fi
####
####if [ -f '/usr/share/doc/pkgfile/command-not-found.bash' ]; then
####    source '/usr/share/doc/pkgfile/command-not-found.bash'
####fi
####
####if [ -f '/usr/share/git/completion/git-prompt.sh' ]; then
####    source '/usr/share/git/completion/git-prompt.sh'
####fi
####
####
######----------------------- Bash Specific ----------------------------------------
####
####       HISTDIR="${XDG_STATE_HOME}/bash"
####export HISTFILE="${HISTDIR}/history"
####
####[ ! -d "${HISTDIR}" ] && mkdir --parents "${HISTDIR}"
####
###### HISTSIZE=-1 means unlimited history
###### HISTSIZE is the number of lines in memory
####export HISTSIZE=10000
####
###### HISTFILESIZE=-1 means unlimited history file ( .bash_history ) size
###### HISTFILESIZE is the number of lines in history file
####export HISTFILESIZE=-1
####
###### ensures that Bash's history will only contain one copy of each command (regardless of order)
####export HISTCONTROL='ignoredups'

##------------------------------------------------------------------------------

## PROMPT_COMMAND=__prompt_Command
## 
## __prompt_Command()
## {
##  var_exit_status_1="$?"
## 
## # Must not modify the lines above this line because exit status of last command has to be captured before doing anything else
## 
##     var_tty="$(tty)"
## 
##  case "${var_tty}" in
## 
##      /dev/tty*)  var_tty_detect=1
##          ;;
##      *)  [ -z "$TMUX" ] && var_tty_detect=0 || var_tty_detect=1
##          ;;
##  esac
## 
##  [ ${var_tty_detect} -eq 1 ] && var_green="$(tput setaf 2)" || var_green="$(tput setaf 35)"
## 
##  [ "${var_exit_status_1}" = "0" ]    && var_exit_status='\['"${var_green}"'\]0\[$(tput sgr0)\]'
##  [ "${var_exit_status_1}" = "1" ]    && var_exit_status='\[$(tput setaf 1)$(tput bold)\]1\[$(tput sgr0)\]'
##  [ "${var_exit_status_1}" != "0" ]   && [ "${var_exit_status_1}" != "1" ] && var_exit_status='\[$(tput setaf 5)\]!\[$(tput sgr0)\]'
##  
## #    if [ ${var_tty_detect} -eq 0 ] ; then
##  if [ ! "linux" = "${TERM}" ] ; then
## 
##      vfc1='\[$(tput setaf 88 )\]'
##      vfc2='\[$(tput setaf 232)\]'
##      vfc3='\[$(tput setaf 82 )\]'
##      vfc4='\[$(tput setaf 32 )\]'
##      vfc5='\[$(tput setaf 250)\]'
##      vfc6='\[$(tput setaf 239)\]'
##      vfc7='\[$(tput setaf 21 )\]'
##      vbc1='\[$(tput setab 239)\]'
##      vbc2='\[$(tput setab 88 )\]'
##      vbc3='\[$(tput setab 82 )\]'
##      vbc4='\[$(tput setab 32 )\]'
##      vbc5='\[$(tput setab 21 )\]'
##       va1='\[$(tput sgr0 )\]'
## #         va2='\[$(tput bold )\]'
##                  va2=''
##       va3='\[$(tput blink)\]'
## 
##      var_output_end="${va1}${vfc1}${va1}"
## 
##      if [ -d '.git' ] ; then
## 
##          var_git_status="$(printf "%s\n" "${va1}${vfc1}${vbc3} ${vfc2}git")"
##          var_output_end="${var_git_status}${va1}${vfc3}${va1}"
## 
##      fi
## 
##      if [ "${PWD}" = "${HOME}"'/HWD' ]; then 
## 
##                     var_bash_home="$(printf "%s%s\u210D\n" "${va1}${vfc1}${vbc5}" "${vfc2}")"
##          var_output_end="${var_bash_home}${va1}${vfc7}${va1}"
##      fi
## 
##      var_pts="$(tty)"
##      var_pts="${var_pts#/dev}"
## 
##                 var_output_line1="$(printf "%s\n" "${va1}${vfc5}${vbc1}[\j]${vfc6}${vbc4}${vfc2}${vbc4}${var_pts}${vfc4}${vbc2}${vfc5}${vbc2}\t${var_output_end}")"
## 
##      var_status_line="${var_output_line1}\n[${var_exit_status}]"'\\$'
##  else
##      var_current_tty="$(cat /sys/class/tty/tty0/active)"
##      var_status_line="[${var_exit_status}][${var_current_tty}]"'[\t]\\$'
##  fi
## 
##         if [ '1' = "${FBTERM}" ] && [ ! "${TMUX}" ] ; then
##             var_prefix=''
##         else
##             var_prefix="\[\e]2;\u : \w\a\]"
##         fi
##  var_postfix="\[$(tput sgr0)\] "
## 
##         PS1="${var_prefix}"${var_status_line}"${var_postfix}"
## }

# # >>> conda initialize >>>
# # !! Contents within this block are managed by 'conda init' !!
# __conda_setup="$('/home/atom/.local/share/miniforge/miniforge3/bin/conda' 'shell.bash' 'hook' 2> /dev/null)"
# if [ $? -eq 0 ]; then
#     eval "$__conda_setup"
# else
#     if [ -f "/home/atom/.local/share/miniforge/miniforge3/etc/profile.d/conda.sh" ]; then
#         . "/home/atom/.local/share/miniforge/miniforge3/etc/profile.d/conda.sh"
#     else
#         export PATH="/home/atom/.local/share/miniforge/miniforge3/bin:$PATH"
#     fi
# fi
# unset __conda_setup
# 
# if [ -f "/home/atom/.local/share/miniforge/miniforge3/etc/profile.d/mamba.sh" ]; then
#     . "/home/atom/.local/share/miniforge/miniforge3/etc/profile.d/mamba.sh"
# fi
# # <<< conda initialize <<<

## ble.sh
## Add the following line at the end of ~/.bashrc
[[ ${BLE_VERSION-} ]] && ble-attach

some more info:

bash-5.2$ pwd
/usr/share/blesh
bash-5.2$ tree
.
├── ble.sh
├── keymap
│   ├── emacs.rlfunc.txt
│   ├── emacs.sh
│   ├── vi.sh
│   ├── vi_digraph.sh
│   ├── vi_digraph.txt
│   ├── vi_imap.rlfunc.txt
│   ├── vi_nmap.rlfunc.txt
│   └── vi_test.sh
└── lib
    ├── core-complete.sh
    ├── core-edit.ignoreeof-messages.txt
    ├── core-syntax.sh
    ├── init-bind.sh
    ├── init-cmap.sh
    ├── init-term.sh
    └── vim-surround.sh

3 directories, 16 files
akinomyoga commented 5 months ago

You seem to use ble-0.3. There are many adjustments related to modifyOtherKeys in ble-0.4, so could you please check if the problem also arises in ble-0.4?

ragnarov commented 5 months ago

ble-0.4.0-devel3.tar.xz In this version, the issues don't exist so far as I have seen.

akinomyoga commented 5 months ago

Hmm, in that case, I wouldn't fix ble-0.3 because so many changes have been implemented for the terminal detection in ble-0.4, and it is not simple to backport all of them to ble-0.3. Would you mind using ble-0.4 instead of ble-0.3?

ragnarov commented 5 months ago

I will use ble-0.4 now. But something else I forgot to mention, If I start a shell from within ranger by pressing S, and then quit the shell with exit or ctrl+d shift key no longer works, instead I get : in command bar of ranger. ranger -> bash -> quit -> back to ranger problem occurs if I start ranger (say 1) from ble.sh session, this problem don't occur, however if I start a nested bash session from within this ranger (1) session, and quit that bash session, and then try to press shift, the same problem occurs. bash(ble.sh) -> ranger -> bash(ble.sh) -> quit -> back to ranger problem occurs

This same problem with shift key and ranger existed in ~0.3

akinomyoga commented 5 months ago

shift key no longer works, instead I get : in command bar of ranger.

Thank you for the information, but what does "shift key no longer works" mean? I'm not familiar with ranger, but as far as I test, just pressing shift doesn't seem to do anything even without ble.sh.

It does something when the shift key is combined with the s key to produce S as you describe. But, that still works after starting a ble.sh session by pressing S and exiting the ble.sh session by running exit or pressing C-d. In this sense, the shift key seems to continue to work even after exiting from the inside ble.sh session in my environment.

How can I check or did you check whether "shift key works"? I think with the normal setup, just pressing shift doesn't do anything by default. The shift key needs to be combined with any other key to cause an action. Then, it is unclear whether you have an effect even without combining shift with another key or you combine the shift key with a key that you didn't describe.

ragnarov commented 5 months ago

thank you for replying, shift key works as in shift + s = S so, if I start ranger from bash, shift key works as previously said (shift + s = S) but bash -> ranger -> bash (shift + s) -> back to ranger (exit) -> now in ranger, shift + s first gives :, and then if I press s again, without lifting shift, I get this : [27;2;83~ But it seems this happens only in foot, don't happen in lxterminal, and urxvt

What software did you use to record your ble.sh session, with the key press shown at bottom right?

akinomyoga commented 5 months ago

OK, I tried other terminals, and I found that the behavior seems to reproduce in mintty when I exit the inside session with C-d. The behavior doesn't seem to reproduce when I exit the inside session by running exit.

What software did you use to record your ble.sh session, with the key press shown at bottom right?

That is a Windows software. A modified version of brookhong/KeyCastOW.

ragnarov commented 5 months ago

I agree, I was wrong. The problem only occurs when exiting the "inside bash" session using c-d for foot terminal and the problem stays in ranger only, if I exit ranger session, And drop to the "first bash" session, and then start ranger again, There is no problem. But If I again start another "inside bash" session, and then exit that with c-d, The ranger session again has this problem. If I exit ranger, this is fixed (as in launching a new ranger session doesn't have this problem)

Edit: Here is a small demonstration I created.

2024_02_05-22_58_27

akinomyoga commented 5 months ago

Sorry for the delay, but I'll later fix it on my side as I can reproduce the problem in my environment. After fixing it, I'll push the fix and ask you to check the behavior in your environment.

akinomyoga commented 4 months ago

I pushed a fix 38a8d571502c699c3b23f8d9313756870862f131. Could you update ble.sh by running ble-update and see if the problem is fixed?

Summary: The behavior of the EXIT trap has changed from Bash 5.2, which caused the issue. When the exit command is called inside a function, the EXIT trap was called after we went out from the function in Bash < 5.2. However, from Bash 5.2, the EXIT trap started to be called from inside the function. When stdout/stderr of the function call is redirected, the EXIT trap is also affected by the redirections from Bash 5.2. See the following example:

$ bash-5.1 -c 'trap "echo hello" EXIT; function fn { exit; }; fn &>/dev/null'
hello
$ bash-5.2 -c 'trap "echo hello" EXIT; function fn { exit; }; fn &>/dev/null'
$

For this reason, necessary terminal control sequences to restore the terminal state did not reach the terminal when the ble.sh session terminated in a specific way in Bash 5.2. The fix was to explicitly redirect the output to the terminal inside the EXIT trap.

ragnarov commented 4 months ago

Thank you so much. That issue has been fixed, But there is a new issue now. When I start the "inside bash session" from ranger, I get the following, using foot terminal.

[i]bash-5.2$ ranger
[i]bash-5.2$ bash: 33: Bad file descriptor
bash: 33: Bad file descriptor
bash: 33: Bad file descriptor
bash: 33: Bad file descriptor

This is what I get using lxterminal right when I launch the terminal. meaning original ble.sh session

[i]bash-5.2$ ranger
[i]bash-5.2$ bash: 33: Bad file descriptor
bash: 33: Bad file descriptor
bash: 33: Bad file descriptor
bash: 33: Bad file descriptor

Edit: okay, after rebooting, that issue is gone. But here is what I get when exiting "inside bash session" using c-d or exit:

[i]bash-5.2$ ranger
[i]bash-5.2$ exit
[ble: exit]
ble: Please run `stty sane' to recover the correct TTY state.
[i]bash-5.2$ 

For both foot and lxterminal

akinomyoga commented 4 months ago

When I start the "inside bash session" from ranger, I get the following,

It should be related to f940696f. I expected it to happen when the new version of ble.sh in a child Bash is started in a parent Bash with an old version of ble.sh, so I thought I added a guard to prevent it from happening. But maybe the guard didn't work properly, or there is a case that I overlooked. I'll later try to replicate it.

But here is what I get when exiting "inside bash session" using c-d or exit:

[i]bash-5.2$ ranger
[i]bash-5.2$ exit
[ble: exit]
ble: Please run `stty sane' to recover the correct TTY state.
[i]bash-5.2$ 

For both foot and lxterminal

That's expected. That is a workaround for Bash 5.2's EXIT trap. When the parent process is not a ble.sh session, the user needs to run stty sane. ble.sh also runs a command equivalent to stty sane, but Bash 5.2 again changes back the TTY state after ble.sh adjusts it.

But I recently added another fix 38a8d571, which might fixed the original problem. I'll take a look.

akinomyoga commented 4 months ago

It took some time to investigate them, implement the solutions, and test the fixed version, but I now pushed the fixes.

This is what I get using lxterminal right when I launch the terminal. meaning original ble.sh session

[i]bash-5.2$ ranger
[i]bash-5.2$ bash: 33: Bad file descriptor
bash: 33: Bad file descriptor
bash: 33: Bad file descriptor
bash: 33: Bad file descriptor

Edit: okay, after rebooting, that issue is gone.

I added a workaround for this in commit 785267e. Even though the error only happened when different versions of ble.sh were mixed, it shouldn't have happened ideally. Now I believe the error of the bad file descriptor doesn't happen in the latest version even when there are file descriptors prepared by previous versions of ble.sh.

But here is what I get when exiting "inside bash session" using c-d or exit:

[i]bash-5.2$ ranger
[i]bash-5.2$ exit
[ble: exit]
ble: Please run `stty sane' to recover the correct TTY state.

As I've explained in my previous reply, this was a workaround for the recent Bash version and actually expected. However, after that, I again took the time to investigate what was happening there. Then, I found the root cause and added a better workaround in commit 4b8a07994d67ebcba4771130c1689b9b8767bad6. Now I removed the message ble: Please run `stty sane` to recover the correct TTY state.

akinomyoga commented 4 months ago

@ragnarov Is everything fine? Can I close the issue?

ragnarov commented 4 months ago

yes please, thank you so much for replying and fixing these issues.

akinomyoga commented 4 months ago

Thank you for all your reports!!