emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[nongnu] elpa/bash-completion 1826ecf46e: Avoid executing PROMPT_COMMAND


From: ELPA Syncer
Subject: [nongnu] elpa/bash-completion 1826ecf46e: Avoid executing PROMPT_COMMAND when doing completion.
Date: Thu, 9 Mar 2023 11:02:42 -0500 (EST)

branch: elpa/bash-completion
commit 1826ecf46e52f6c0cf21839c3af796a5cb858779
Author: Stephane Zermatten <szermatt@gmx.net>
Commit: Stephane Zermatten <szermatt@gmx.net>

    Avoid executing PROMPT_COMMAND when doing completion.
    
    Before this change, PROMPT_COMMAND was sometimes allowed to execute
    during the first completion in a Bash process. This caused confusion in
    the case where PROMPT_COMMAND does more than just printing data.
    
    With this change, PROMPT_COMMAND is guaranteed to be stored and then
    cleared in the very first command set to a Bash process, together with
    PS1.
    
    Note that this lengthens the commands sent to Bash, to the point where
    they were getting too long when defining functions, so initial function
    definition has been split into two Bash commands instead of one.
    
    For background, see discussion on issue #63
---
 bash-completion.el                       | 25 +++++++++++++++++--------
 test/bash-completion-integration-test.el | 12 +++++-------
 2 files changed, 22 insertions(+), 15 deletions(-)

diff --git a/bash-completion.el b/bash-completion.el
index b566c9cfdb..caddeac1be 100644
--- a/bash-completion.el
+++ b/bash-completion.el
@@ -413,7 +413,10 @@ returned."
            (bash-completion--side-channel-data "compopt" "${_EMACS_COMPOPT}")
            " fi;"
            " return $n;"
-           "} ; function compopt {"
+           "}")
+   process)
+  (bash-completion-send
+   (concat "function compopt {"
            " command compopt \"$@\" 2>/dev/null;"
            " local ret=$?; "
            " if [[ $ret == 1 && \"$*\" = *\"-o nospace\"* ]]; then"
@@ -1492,7 +1495,14 @@ Return the status code of the command, as a number."
             (bash-completion-use-separate-processes "%s\n")
             ;; single process, assume __ebcpre is already defined
             ((not define-functions)
-             "if type __ebcpre &>/dev/null; then __ebcpre; %s; else echo 
==emacs==nopre=${BASH_VERSION}==.; fi;\n")
+             (concat
+              "if type __ebcpre &>/dev/null; then "
+              "  __ebcpre; %s; "
+              "else "
+              "  echo ==emacs==nopre=${BASH_VERSION}==.; "
+              "  __ebcp=(\"$PS1\" \"$PROMPT_COMMAND\");"
+              "  unset PS1 PROMPT_COMMAND;"
+              "fi;\n"))
             ;; single process, define __ebcpre
             (t
               (concat
@@ -1505,9 +1515,8 @@ Return the status code of the command, as a number."
                "}; function __ebcpre {"
                "  set +x; set +o emacs; set +o vi;"
                "  echo \"==emacs==bash=${BASH_VERSION}==.\";"
-               "  if [[ -z \"${__ebcps1}\" ]]; then "
-               "    __ebcps1=\"$PS1\";"
-               "    __ebcpc=\"$PROMPT_COMMAND\";"
+               "  if [[ ${#__ebcp[@]} = 0 ]]; then "
+               "    __ebcp=(\"$PS1\" \"$PROMPT_COMMAND\");"
                "  fi;"
                "  PROMPT_COMMAND=" ;; set a temporary prompt
                (bash-completion-quote
@@ -1516,9 +1525,9 @@ Return the status code of the command, as a number."
                         (bash-completion-quote
                          (concat
                           "__ebcr=$?;"
-                          "PS1=\"${__ebcps1}\";"
-                          "PROMPT_COMMAND=\"${__ebcpc}\";"
-                          "unset __ebcps1 __ebcpc;"
+                          "PS1=\"${__ebcp[0]}\";"
+                          "PROMPT_COMMAND=\"${__ebcp[1]}\";"
+                          "unset __ebcp;"
                           "if [[ -n \"$PROMPT_COMMAND\" ]]; then"
                           "  (exit $__ebcr); eval \"$PROMPT_COMMAND\";"
                           "fi;"))))
diff --git a/test/bash-completion-integration-test.el 
b/test/bash-completion-integration-test.el
index a0d15abb6d..750687597a 100644
--- a/test/bash-completion-integration-test.el
+++ b/test/bash-completion-integration-test.el
@@ -647,17 +647,15 @@ PROMPT_COMMAND=_prompt
    (bash-completion_test-send "ls -1 morete" 'complete)
    (bash-completion_test-send "tru" 'complete)
    (bash-completion_test-send "fals" 'complete)
-   ;; One call to PROMPT_COMMAND is deleted: the one called the 1st
-   ;; time completion is attempted. The output of PROMPT_COMMAND is
-   ;; deleted, but not the fact that it ran. This is while [1] is
-   ;; skipped.
+   ;; PROMPT_COMMAND is reset early on to avoid ever running it when
+   ;; doing completion.
    (should (equal
             (bash-completion_test-buffer-string)
             "[0]:0 $ ls -1 moretestfile
 moretestfile
-[2]:0 $ true
-[3]:0 $ false
-[4]:1 $ "))))
+[1]:0 $ true
+[2]:0 $ false
+[3]:1 $ "))))
 
 (ert-deftest bash-completion-integration-ps1 ()
   "Tests PS1 storage and recovery in single-process mode."



reply via email to

[Prev in Thread] Current Thread [Next in Thread]