-
Notifications
You must be signed in to change notification settings - Fork 93
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Request for public/stable APIs to enable/disable the hooks and to manually invoke registered functions #129
base: master
Are you sure you want to change the base?
Conversation
Can you provide some pointers for this behavior? What is more "proper" about your approach? |
Maybe the word choice proper was not the appropriate one. I'm not a native speaker so don't know what would be the best-fit word for this case, but ble.sh is an alternative implementation of a line editor. Everything including the prompt calculation and command execution is under the control of
It depends on what kind of information you need, but if you need the information on the interface of these hooks, it is explained in §1.2.2 of the manual. If you need the implementation details, it is hard to point one place because ble.sh implements an entire line editor and requires reading larger code sections to understand the whole execution flow, but Edit (2022-02-20): If you are interested in how these APIs can be used from the framework that provides precmd and preexec mechanisms, you can read |
01bfc4e
to
1c82488
Compare
I have added code comments to explain the new functions and force-pushed the changes. The overall diff of the forced push is here.diff --git a/bash-preexec.sh b/bash-preexec.sh
index f1758d3..06db478 100644
--- a/bash-preexec.sh
+++ b/bash-preexec.sh
@@ -153,6 +153,9 @@ __bp_precmd_invoke_cmd() {
bash_preexec_invoke_precmd_functions "$__bp_last_ret_value" "$__bp_last_argument_prev_command"
}
+# This function invokes every function defined in our function array
+# "precmd_function". This function receives the arguments $1 and $2 for $? and
+# $_, respectively, that will be set for the precmd functions.
bash_preexec_invoke_precmd_functions() {
local __lastexit=$1 __lastarg=$2
# Invoke every function defined in our function array.
@@ -267,8 +270,12 @@ __bp_preexec_invoke_exec() {
__bp_set_ret_value "$preexec_ret_value" "$__bp_last_argument_prev_command"
}
-# This function invokes every function defined in our function array. This
-# function assigns the last error exit status to the variable
+# This function invokes every function defined in our function array
+# "preexec_function". This function receives the arguments $1 and $2 for $?
+# and $_, respectively, that will be set for the preexec functions. The third
+# argument $3 specifies the user command that is going to be executed
+# (corresponding to BASH_COMMAND in the DEBUG trap). This function assigns the
+# last non-zero exit status from the preexec functions to the variable
# `preexec_ret_value`. If there is no error, preexec_ret_value is set to `0`.
bash_preexec_invoke_preexec_functions() {
local __lastexit=$1 __lastarg=$2 __this_command=$3
@@ -367,6 +374,7 @@ __bp_install_after_session_init() {
PROMPT_COMMAND+=${bash_preexec_install_string}
}
+# Remove hooks installed in the DEBUG trap and PROMPT_COMMAND.
bash_preexec_uninstall() {
# Remove __bp_install hook from PROMPT_COMMAND
if [[ ${PROMPT_COMMAND-} == *"$bash_preexec_install_string"* ]]; then
@@ -389,6 +397,7 @@ bash_preexec_uninstall() {
fi
fi
}
+declare -ft bash_preexec_uninstall
# Run our install so long as we're not delaying it.
if [[ -z "${__bp_delay_install:-}" ]]; then P.S. If we need to describe the new APIs in README, I can also add the description there. Supported Bash versionsBy the way, what is the minimal Bash version that PROMPT_COMMAND=${PROMPT_COMMAND/#$'__bp_precmd_invoke_cmd\n'/$'\n'}
PROMPT_COMMAND=${PROMPT_COMMAND%$'\n__bp_interactive_mode'}
PROMPT_COMMAND=${PROMPT_COMMAND#$'\n'} |
@akinomyoga Thanks for the PR and support of this project. I'll take a look and chime in before end of week! |
} | ||
|
||
# Remove hooks installed in the DEBUG trap and PROMPT_COMMAND. | ||
bash_preexec_uninstall() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not convinced that bash-preexec should be responsible for maintaining any over head of uninstalling itself from both trap and prompt_command. Any libraries using these shared variables have more or less had to clean them up and maintain them on their own, as does bash-preexec with its installation. With the defined global variables what's stopping from just implementing this in your own library?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With the defined global variables what's stopping from just implementing this in your own library?
If the setup of bash-preexec.sh
would never change in the future forever, I could just assume the current setup of bash-preexec.sh
and write a code to clean up the things that are installed by the current bash-preexec.sh
.
However, if the __bp_install
configuration can change in the future (e.g. as suggested in #128), the cleanup code also needs to be updated. I don't think it is a good idea to update the cleanup code at the users' side every time the __bp_install
configuration of bash-preexec.sh
is changed. In particular, if the method of uninstalling the hooks would not be provided by bash-preexec.sh
, the user/library needs to maintain the separate cleanup code for each of all the past versions of bash-preexec.sh
and to detect the precise version of bash-preexec.sh
.
This is actually the reason that I would like to request the "stable" public API rather than relying on the details of the internal implementation that can be frequently changed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I get your reasoning and desire for this as a way to help with your library and not just implementing it yourself. I just think there's no real standard here I've seen other libraries that have clashed with bash-preexec as well since they also make the assumption they'll have access to these parts of the system configuration. (Liquid Prompt is one example) My assumption is, these too can cause issues with ble.sh and we're trying to chase individual fires here.
I am concerned that this is an esoteric use case and will likely just add operational overhead to maintaining it. With that said, if any other contributors see value in this I'm supportive.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. Maybe I miss your exact point (What does "the system configuration" mean?), but I think I'll later need to look at Liquid Prompt.
@akinomyoga thanks again for the PR and trying to help make bash-preexec better. This small library has gotten more widely used across other projects/companies than ever originally anticipated. As such, it's definitely opinionated toward original use cases and has clashed withe other libraries over shared state like I think I'm open to most of this change provided it's not breaking. Left comments and questions in line.
I think 3.1 sounds right. Unless there's some other feature being used that would date it later. We should add this to the documentation at the top. |
01527e5
to
4caf63c
Compare
Thank you for your careful review and valuable comments! I have addressed or commented on the points that you have raised in each review comment. edit: I have also rebased it on top of the current
Thank you for the clarification! Maybe we might also add the version check at the beginning of |
Sure. Feel free to add in separate commit if you'd like. Not necessary in this stack. |
} | ||
|
||
# Remove hooks installed in the DEBUG trap and PROMPT_COMMAND. | ||
bash_preexec_uninstall() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I get your reasoning and desire for this as a way to help with your library and not just implementing it yourself. I just think there's no real standard here I've seen other libraries that have clashed with bash-preexec as well since they also make the assumption they'll have access to these parts of the system configuration. (Liquid Prompt is one example) My assumption is, these too can cause issues with ble.sh and we're trying to chase individual fires here.
I am concerned that this is an esoteric use case and will likely just add operational overhead to maintaining it. With that said, if any other contributors see value in this I'm supportive.
@dimo414 or any other contributors have thoughts on the necessity of an uninstall function i.e. the proposed |
I have noticed that an existing test for bash-preexec/test/bash-preexec.bats Lines 53 to 59 in d308800
Here, line 58 should be However, now I believe we can and should use |
@akinomyoga thanks for updating with tests. Looks good. Will hold for any other feedback/input from other contributors. |
4a37150
to
697b588
Compare
697b588
to
fa43a27
Compare
There was a conflict, so I rebased and squashed commits. |
* Rename public functions and variables as "bash_preexec_*" * Remove the compatibility variable name "__bp_install_string" * Do not prefix local varnames with underscores * Make "bash_preexec_invoke_pre{cmd,exec}_functions" return the last non-zero exit status * Add a note on the "trace" function attribute * Preserve the previous exit status and argument * Test the installation of convenience functions * Test "bash_preexec_uninstall" * Test "bash_preexec_invoke_pre{cmd,exec}_functions"
fa43a27
to
3305f42
Compare
bash-preexec
relies on theDEBUG
trap (forpreexec
) andPROMPT_COMMAND
(forprecmd
). In particular, the hook using theDEBUG
trap is a kind of hack and fragile. TheDEBUG
trap is called for every single shell command (of the top-level whenset -T
orshopt -s extdebug
is not set), which makes the execution slower. TheDEBUG
trap can interfere with other Bash configurations that use theDEBUG
trap. The implementation ofpreexec
by theDEBUG
trap also causes problems like #115, #104, #116, #100, #25, and #6. The hook usingPROMPT_COMMAND
(forprecmd
) is not so stable, in particular when other configurations add settings such asPROMPT_COMMAND="${PROMPT_COMMAND+$PROMPT_COMMAND;}__new_settings__"
(see #128 for example).Therefore, when the other framework provides proper support for the
preexec
andprecmd
hooks, it would be better to just use them instead of relying on fragileDEBUG
andPROMPT_COMMAND
. To allow users or other Bash configuration frameworks to choose howprecmd
andpreexec
ofbash-preexec
will be invoked, I would like to request public/stable APIs to install/uninstallDEBUG
andPROMPT
hooks in arbitrary timing and also the public/stable APIs to invoke{precmd,preexec}_functions
from external mechanisms ofpreexec
andprecmd
.The public APIs that I would like to request in this PR are:
preexec_functions
bash_preexec_invoke_preexec_functions
in this PR.precmd_functions
bash_preexec_invoke_precmd_functions
in this PR.DEBUG
andPROMPT_COMMAND
bash_preexec_install_string
in this PR, which was originally named__bp_install_string
.bash-preexec
registers to theDEBUG
trapbash_preexec_trapdebug_string
in this PR.DEBUG
andPROMPT_COMMAND
bash_preexec_uninstall
. This is a new feature that did not exist previously.About the API names
I have initially created commit fe46a97 with the existing naming convention of
__bp_*
. However, now we have merged #123 wherebash_preexec_*
has been adopted as the name for the public interfaces, so I have followed the new convention in commit 01bfc4e. I can adjust these naming if there are any requests.Background
In my project of Bash configuration (ble.sh), I have so far received issues caused by the interference with
bash-preexec
several times. I have been trying to make the Bash configuration work withbash-preexec
, but there is still a limitation, and it is hard to make it work perfectly (including the other issues that are reported in this upstream repository).ble.sh
actually provides proper support for thePRECMD
andPREEXEC
hooks, so I would like to recommend users to use them instead ofbash-preexec
, but there are many existing settings and configurations that rely onbash-preexec
. Also, I don't want to unnecessarily require users to create dependency on ble.sh. So I decided to rewrite the hooks bybash-preexec
whenble.sh
detects it. Currently,ble.sh
assumes many things about the internals ofbash-preexec
in rewriting the hooks bybash-preexec
, which is not ideal. What I actually need is just several public/stable APIs just I described above.Related discussions: