Bash-it / bash-it

A community Bash framework.
MIT License
14.14k stars 2.29k forks source link

Does `bash-it` load `bash-preexec` by default? #2244

Closed hongyi-zhao closed 4 months ago

hongyi-zhao commented 4 months ago

After I installed bash-it, I noticed that the $PROMPT_COMMAND variable changed to the following:

werner@X10DAi:~$ echo $PROMPT_COMMAND
__bp_precmd_invoke_cmd __hishtory_postcommand; _zlua_precmd;_pyenv_virtualenv_hook __bp_interactive_mode

So, it seems that bash-it loads bash-preexec by default. Is this a mandatory requirement or not? If not, how can I disable it?

Regards, Zhao

hongyi-zhao commented 4 months ago

To inspect the variable's value of PROMPT_COMMAND set by bash_it.sh, I tried the following method: first, unset this variable immediately before bash_it.sh was sourced and then check its value immediately after bash_it.sh was sourced. By this way, I noticed the following result:

__hishtory_postcommand; _zlua_precmd;_pyenv_virtualenv_hook __bp_trap_string="$(trap -p DEBUG)" trap - DEBUG __bp_install

In my case, a further checking tells me that the __hishtory_postcommand comes from config.sh of the hishtory package and __bp_trap_string="$(trap -p DEBUG)" trap - DEBUG __bp_install comes from bash-it.

But, as for how they finally changed to __bp_precmd_invoke_cmd and __bp_interactive_mode, I'm still not quite sure.

akinomyoga commented 4 months ago

I'm still not quite sure.

That's processed in bash-preexec.sh.

bash-preexec.sh wants to call __bp_precmd_invoke_cmd before any other PROMPT_COMMAND, and it also wants to call __bp_interactive_mode at the very end of PROMPT_COMMAND. This setup can be broken when other frameworks set PROMPT_COMMAND for them after bash-preexec.sh introduces its setup. For this reason, bash-preexec.sh delays its initialization until the first call of PROMPT_COMMAND. The string __bp_trap_string="$(trap -p DEBUG)"\ntrap - DEBUG __bp_install is the code to call the initialization. The strings __bp_precmd_invoke_cmd and __bp_interactive_mode are the strings set by the bash-preexec's initialization (in particular by the shell function __bp_install).

akinomyoga commented 4 months ago

In the codebase of Bash-it, the feature provided by bash-preexec seems to be used in the following places:

Also, the following plugin indirectly uses bash-preexec through plugin command_duration:

As far as you don't use those features, I think you can technically skip loading bash-preexec by commenting out this line:

https://github.com/Bash-it/bash-it/blob/d985e4c96b1eb4e7374b3ab53eea3513fc9f50ce/lib/preexec.bash#L12

hongyi-zhao commented 4 months ago

Also, the following plugin indirectly uses bash-preexec through plugin command_duration:

According to the discussion here, bash-preexec often gives inaccurate, usually overestimated command_duration.

As far as you don't use those features, I think you can technically loading bash-preexec by commenting out this line:

This will trigger the following problem:

__bp_install_after_session_init: command not found

So, the following line also needs to be commented out: https://github.com/Bash-it/bash-it/blob/d985e4c96b1eb4e7374b3ab53eea3513fc9f50ce/lib/preexec.bash#L25

After making the above modifications, the PROMPT_COMMAND will finally look as follows:

werner@X10DAi:~$ echo $PROMPT_COMMAND
_bash-it-history-auto-load;_command_duration_pre_cmd;__hishtory_postcommand; _zlua_precmd;_pyenv_virtualenv_hook

BTW, it may be more convenient to provide options to enable and disable these features.

akinomyoga commented 4 months ago

Also, the following plugin indirectly uses bash-preexec through plugin command_duration:

According to the discussion here, bash-preexec often gives inaccurate, usually overestimated command_duration.

Right. That problem is ubiquitous as far as bash-preexec or a similar approach using the DEBUG hook is used.

As far as you don't use those features, I think you can technically loading bash-preexec by commenting out this line:

It may be more convenient to provide options to enable and disable these features.

Probably.

This will trigger the following problem:

__bp_install_after_session_init: command not found

Then, you can also comment out this line:

https://github.com/Bash-it/bash-it/blob/d985e4c96b1eb4e7374b3ab53eea3513fc9f50ce/lib/preexec.bash#L25

cornfeedhobo commented 4 months ago

So, it seems that bash-it loads bash-preexec by default. Is this a mandatory requirement or not? If not, how can I disable it?

Indeed, bash-preexec is a requirement for bash-it, currently.