From ceff195198a09939c3ea0766a054c4fc0cffcc35 Mon Sep 17 00:00:00 2001 From: Koichi Murase Date: Mon, 8 Jul 2024 15:11:32 +0900 Subject: [PATCH 1/7] Use [[ -o vi ]] to test the vi editing mode in Bash --- mcfly.bash | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mcfly.bash b/mcfly.bash index f33271c..624bea8 100644 --- a/mcfly.bash +++ b/mcfly.bash @@ -128,7 +128,7 @@ function mcfly_initialize { # 2. Type "mcfly search" and then run the command. McFly will pull the last line from the $MCFLY_HISTORY file, # which should be the commented-out search from step #1. It will then remove that line from the history file and # render the search UI pre-filled with it. - if set -o | grep "vi " | grep -q on; then + if [[ -o vi ]]; then bind '"\C-r": "\e0i#mcfly: \e\C-m mcfly search\C-m"' else bind '"\C-r": "\C-amcfly: \e# mcfly search\C-m"' From 2d48b1512562dcf966557ee8f1bc51700c4e8163 Mon Sep 17 00:00:00 2001 From: Koichi Murase Date: Mon, 8 Jul 2024 15:40:23 +0900 Subject: [PATCH 2/7] Use "builtin type" to locate "mcfly" The command "which" is a non-POSIX external command, and technically, its existence in the system is not ensured. We here use Bash's built-in command "type", which is the most reliable. We prefix "builtin" to "type" because some users overwrite "type" with a shell function or an alias to mimic Windows' "type" command. The use of the which command was first removed in Ref. [1]. However, this was reverted after the issue in Ref. [2]. As far as a relative path is not contained in PATH, the problem reported in Ref. [2] does not seem to be reproducible in all the versions from Bash 3.0 to 5.2 and in the devel branch of Bash. However, when the path "./bin" is included in PATH, the "command -v" produces the relative path "./bin/mcfly" as reported. This seems to have been solved by using the "which command in the reporter's environment, but the behavior of the "which" command may depend on the implementation. We should explicitly resolve the relative path if the obtained MCFLY_PATH is relative. References: [1] https://github.com/cantino/mcfly/pull/216 [2] https://github.com/cantino/mcfly/issues/292 [3] https://github.com/cantino/mcfly/pull/430#discussion_r1685817139 --- mcfly.bash | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/mcfly.bash b/mcfly.bash index 624bea8..d015835 100644 --- a/mcfly.bash +++ b/mcfly.bash @@ -27,7 +27,12 @@ function mcfly_initialize { export MCFLY_SESSION_ID # Find the binary - MCFLY_PATH=${MCFLY_PATH:-$(command which mcfly)} + MCFLY_PATH=${MCFLY_PATH:-$(builtin type -P mcfly)} + if [[ $MCFLY_PATH != /* ]]; then + # When the user include a relative path in PATH, "builtin type -P" may + # produce a relative path. We convert relative paths to the absolute ones. + MCFLY_PATH=$PWD/$MCFLY_PATH + fi if [[ -z $MCFLY_PATH ]]; then echo "Cannot find the mcfly binary, please make sure that mcfly is in your path before sourcing mcfly.bash." return 1 From 78e75c76ab88a9bc0d1a0099134fcd8b264247a5 Mon Sep 17 00:00:00 2001 From: Koichi Murase Date: Mon, 8 Jul 2024 15:26:55 +0900 Subject: [PATCH 3/7] Do not export MCFLY_BASH_*_KEYBINDING unused by the mcfly binary in Bash --- mcfly.bash | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mcfly.bash b/mcfly.bash index d015835..7684ecf 100644 --- a/mcfly.bash +++ b/mcfly.bash @@ -15,8 +15,8 @@ function mcfly_initialize { # Setup MCFLY_HISTFILE and make sure it exists. export MCFLY_HISTFILE="${HISTFILE:-$HOME/.bash_history}" - export MCFLY_BASH_SEARCH_KEYBINDING=${MCFLY_BASH_SEARCH_KEYBINDING:-"\C-x1"} - export MCFLY_BASH_ACCEPT_LINE_KEYBINDING=${MCFLY_BASH_ACCEPT_LINE_KEYBINDING:-"\C-x2"} + MCFLY_BASH_SEARCH_KEYBINDING=${MCFLY_BASH_SEARCH_KEYBINDING:-"\C-x1"} + MCFLY_BASH_ACCEPT_LINE_KEYBINDING=${MCFLY_BASH_ACCEPT_LINE_KEYBINDING:-"\C-x2"} if [[ ! -r ${MCFLY_HISTFILE} ]]; then echo "McFly: ${MCFLY_HISTFILE} does not exist or is not readable. Please fix this or set HISTFILE to something else before using McFly." return 1 From 7289d702f8f65cd6539b7ad2203293ad5e75a6bc Mon Sep 17 00:00:00 2001 From: Koichi Murase Date: Mon, 8 Jul 2024 15:36:50 +0900 Subject: [PATCH 4/7] Check existence of the executable file at MCFLY_PATH This is to avoid later error messages in the case MCFLY_PATH contained an invalid/outdated path before the initialization by mcfly.bash. --- mcfly.bash | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mcfly.bash b/mcfly.bash index 7684ecf..d656e16 100644 --- a/mcfly.bash +++ b/mcfly.bash @@ -33,7 +33,7 @@ function mcfly_initialize { # produce a relative path. We convert relative paths to the absolute ones. MCFLY_PATH=$PWD/$MCFLY_PATH fi - if [[ -z $MCFLY_PATH ]]; then + if [[ ! -x $MCFLY_PATH ]]; then echo "Cannot find the mcfly binary, please make sure that mcfly is in your path before sourcing mcfly.bash." return 1 fi From 888a653c6a1409da199a784d08be1d3c8937ac7f Mon Sep 17 00:00:00 2001 From: Koichi Murase Date: Mon, 8 Jul 2024 20:24:28 +0900 Subject: [PATCH 5/7] Use array PROMPT_COMMAND in Bash >= 5.1 We perform this in a shell function to temporarily set IFS. --- mcfly.bash | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/mcfly.bash b/mcfly.bash index d656e16..31d2e48 100644 --- a/mcfly.bash +++ b/mcfly.bash @@ -67,6 +67,25 @@ function mcfly_initialize { return "${exit_code}" # Restore the original exit code by returning it. } + function mcfly_add_prompt_command { + local command=$1 IFS=$' \t\n' + if ((BASH_VERSINFO[0] > 5 || BASH_VERSINFO[0] == 5 && BASH_VERSINFO[1] >= 1)); then + # Bash 5.1 supports array PROMPT_COMMAND, where we register our prompt + # command to a new element PROMPT_COMMAND[i] (with i >= 1) to avoid + # conflicts with other frameworks. + if [[ " ${PROMPT_COMMAND[*]-} " != *" $command "* ]]; then + PROMPT_COMMAND[0]=${PROMPT_COMMAND[0]:-} + PROMPT_COMMAND+=("$command") + fi + elif [[ -z ${PROMPT_COMMAND-} ]]; then + PROMPT_COMMAND="$command" + elif [[ $PROMPT_COMMAND != *"mcfly_prompt_command"* ]]; then + PROMPT_COMMAND="$command;${PROMPT_COMMAND#;}" + fi + } + # Set $PROMPT_COMMAND run mcfly_prompt_command, preserving any existing $PROMPT_COMMAND. + mcfly_add_prompt_command "mcfly_prompt_command" + function mcfly_search_with_tiocsti { local LAST_EXIT_CODE=$? IFS=$' \t\n' echo "#mcfly: ${READLINE_LINE[*]}" >> "$MCFLY_HISTORY" @@ -108,13 +127,6 @@ function mcfly_initialize { return "$LAST_EXIT_CODE" } - # Set $PROMPT_COMMAND run mcfly_prompt_command, preserving any existing $PROMPT_COMMAND. - if [[ -z ${PROMPT_COMMAND-} ]]; then - PROMPT_COMMAND="mcfly_prompt_command" - elif [[ $PROMPT_COMMAND != *"mcfly_prompt_command"* ]]; then - PROMPT_COMMAND="mcfly_prompt_command;${PROMPT_COMMAND#;}" - fi - # Take ownership of ctrl-r. if ((BASH_VERSINFO[0] >= 4)); then # shellcheck disable=SC2016 From f6d65911d9e858e08fdad652a0323c0370e84401 Mon Sep 17 00:00:00 2001 From: Koichi Murase Date: Wed, 17 Jul 2024 13:28:16 +0900 Subject: [PATCH 6/7] Work around Bash 3.0 syntax --- mcfly.bash | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/mcfly.bash b/mcfly.bash index 31d2e48..87d26c2 100644 --- a/mcfly.bash +++ b/mcfly.bash @@ -75,7 +75,10 @@ function mcfly_initialize { # conflicts with other frameworks. if [[ " ${PROMPT_COMMAND[*]-} " != *" $command "* ]]; then PROMPT_COMMAND[0]=${PROMPT_COMMAND[0]:-} - PROMPT_COMMAND+=("$command") + # Note: We here use eval to avoid syntax error in Bash < 3.1. We drop + # the support for Bash < 3.0, but this is still needed to avoid parse + # error before the Bash version check is performed. + eval 'PROMPT_COMMAND+=("$command")' fi elif [[ -z ${PROMPT_COMMAND-} ]]; then PROMPT_COMMAND="$command" From cc372578582ebdab5cce8d90c0e1049dd159b32e Mon Sep 17 00:00:00 2001 From: Koichi Murase Date: Wed, 17 Jul 2024 13:27:59 +0900 Subject: [PATCH 7/7] Check Bash version --- mcfly.bash | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/mcfly.bash b/mcfly.bash index 87d26c2..8e20a96 100644 --- a/mcfly.bash +++ b/mcfly.bash @@ -1,6 +1,13 @@ #!/bin/bash function mcfly_initialize { + # Note: We avoid using [[ ... ]] to check the Bash version because we are + # even unsure whether it is available before confirming the Bash version. + if [ -z "${BASH_VERSINFO-}" ] || [ "${BASH_VERSINFO-}" -lt 3 ]; then + printf 'mcfly.bash: This setup requires Bash >= 3.0.' >&2 + return 1 + fi + unset -f "${FUNCNAME[0]}" # Ensure stdin is a tty