Skip to content
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

Multiline completion problem #356

Open
RBT22 opened this issue Aug 28, 2023 · 7 comments
Open

Multiline completion problem #356

RBT22 opened this issue Aug 28, 2023 · 7 comments

Comments

@RBT22
Copy link

RBT22 commented Aug 28, 2023

ble version: 0.4.0-devel3+1a5c451c
Bash version: 5.1.16(1)-release

Hi,

I encountered a problem with multiline completions when using the ble.sh.
Without it I get nice multilne completions in bash, like this:
Screenshot from 2023-08-28 15-07-02

But when it is activated, the result is separated into multiple options and it doesn't work as intended.
Screenshot from 2023-08-28 15-07-57

Is it something that can be configured in the settings?
Thank you very much for your help in advanced!

@akinomyoga
Copy link
Owner

akinomyoga commented Aug 31, 2023

Thanks for the report, but I cannot identify the problem unless the completion setting is provided. How did you set up the completion for ros2? What is the output of the following command?

$ register-python-argcomplete ros2

# or, if not available, could you try the following instead?

$ register-python-argcomplete3 ros2

@RBT22
Copy link
Author

RBT22 commented Sep 1, 2023

Thank you for the quick response! My settings are the following:

_python_argcomplete() {
    local IFS=$'\013'
    local SUPPRESS_SPACE=0
    if compopt +o nospace 2> /dev/null; then
        SUPPRESS_SPACE=1
    fi
    COMPREPLY=( $(IFS="$IFS" \
                  COMP_LINE="$COMP_LINE" \
                  COMP_POINT="$COMP_POINT" \
                  COMP_TYPE="$COMP_TYPE" \
                  _ARGCOMPLETE_COMP_WORDBREAKS="$COMP_WORDBREAKS" \
                  _ARGCOMPLETE=1 \
                  _ARGCOMPLETE_SUPPRESS_SPACE=$SUPPRESS_SPACE \
                  "$1" 8>&1 9>&2 1>/dev/null 2>/dev/null) )
    if [[ $? != 0 ]]; then
        unset COMPREPLY
    elif [[ $SUPPRESS_SPACE == 1 ]] && [[ "$COMPREPLY" =~ [=/:]$ ]]; then
        compopt -o nospace
    fi
}
complete -o nospace -o default -F _python_argcomplete "ros2"

@akinomyoga
Copy link
Owner

Thank you for your quick response. Could you copy and paste the output of the following command?

$ ( COMP_LINE='ros2 topic pub /cmd_vel geometry_msgs/msg/Twist ' COMP_POINT=${#COMP_LINE} COMP_TYPE=9
    export "${!COMP_@}"
    _ARGCOMPLETE_COMP_WORDBREAKS="$COMP_WORDBREAKS" \
    _ARGCOMPLETE=1 _ARGCOMPLETE_SUPPRESS_SPACE=0 \
    ros2 8>&1 9>&2 1>/dev/null 2>/dev/null)

@RBT22
Copy link
Author

RBT22 commented Sep 1, 2023

-r
  --rate
        -p
          --print
                 -1
                   --once
                         -t
                           --times
                                  -w
                                    --wait-matching-subscriptions
                                                                 --keep-alive
                                                                             -n
                                                                               --node-name
                                                                                          --qos-profile
                                                                                                       --qos-depth
                                                                                                                  --qos-history
                                                                                                                               --qos-reliability
                                                                                                                                                --qos-durability
  --spin-time
             -s
               --use-sim-time
                             linear:\
\ \ x:\ 0.0\
\ \ y:\ 0.0\
\ \ z:\ 0.0\
angular:\
\ \ x:\ 0.0\
\ \ y:\ 0.0\
\ \ z:\ 0.0\

@akinomyoga
Copy link
Owner

Thanks. Hmm, maybe I now know what is happening. What are the outputs of the following two cases?

$ ( COMP_LINE='ros2 topic pub /cmd_vel geometry_msgs/msg/Twist "l' COMP_POINT=${#COMP_LINE} COMP_TYPE=9
    export "${!COMP_@}"
    _ARGCOMPLETE_COMP_WORDBREAKS="$COMP_WORDBREAKS" \
    _ARGCOMPLETE=1 _ARGCOMPLETE_SUPPRESS_SPACE=0 \
    ros2 8>&1 9>&2 1>/dev/null 2>/dev/null)
$ ( COMP_LINE='ros2 topic pub /cmd_vel geometry_msgs/msg/Twist l' COMP_POINT=${#COMP_LINE} COMP_TYPE=9
    export "${!COMP_@}"
    _ARGCOMPLETE_COMP_WORDBREAKS="$COMP_WORDBREAKS" \
    _ARGCOMPLETE=1 _ARGCOMPLETE_SUPPRESS_SPACE=0 \
    ros2 8>&1 9>&2 1>/dev/null 2>/dev/null)

@RBT22
Copy link
Author

RBT22 commented Sep 1, 2023

For the first one:

linear:
  x: 0.0
  y: 0.0
  z: 0.0
angular:
  x: 0.0
  y: 0.0
  z: 0.0

For the second:

linear:\
\ \ x:\ 0.0\
\ \ y:\ 0.0\
\ \ z:\ 0.0\
angular:\
\ \ x:\ 0.0\
\ \ y:\ 0.0\
\ \ z:\ 0.0\
 [ble: EOF] 

@akinomyoga
Copy link
Owner

Thank you. There are two issues.

  • The first one is an assumption on the quoting of the candidates generated by the completion setting.
  • The second is the treatment of the newlines in the compgen builtin, the completion interface of Bash that ble.sh uses.

Assumption on quoting

Bash assumes that the generated candidates are already properly quoted when they don't match filenames by default (and the behavior can be configured by compopt -o filenames and compopt -o noquote.

However, the actual settings for the programmable completions are usually not properly implemented to quote the results. To remedy these half-broken settings, ble.sh assumes by default that the generated candidates are not properly quoted, though this is different from Bash's assumption. On the other hand, the completions generated by python-argparse seem to quote the results properly, which is actually the correct behavior. This causes the difference in the treatment of the backslashes.

This can be easily fixed in ble.sh as it is easy to distinguish the completion settings generated by python-argparse; ble.sh can change the treatment of quoting only for the settings generated by python-argparse.

Newlines in compgen

To use the programmable completion feature of Bash, ble.sh uses the compgen builtin. The compgen builtin can be used to run the programmable completion specified by the user and obtain the results. However, the results are written to stdout separated by newlines, so there is no way to distinguish a newline as a part of a candidate and a newline that separates two candidates.

  • Bash 5.3 (which is still under development and not released) has option -V for compgen that enables writing results to an array variable. With this interface, we do not have to split the results by newlines because each candidate is already stored as an element of the array.

    Even when compgen -V varname is available, there are additional things to consider. ble.sh uses an external command sort to sort the generated results. In that case, we need to join the results by newlines, pass the results to sort through stdin, and split the output of sort again. This procedure also has the newline problem. Some implementation of sort supports the option -z to accept NUL as the entry separator/terminator, but it's not standardized and not available everywhere. In addition to the sorting, we also need to filter the results by the prefix and also try to find the description from the man page database if necessary, which all have the same problem of newlines.

  • Another possibility could be connecting a line ending with an isolated backslash to the next line, which is actually a similar treatment for complete -C cmd by Bash. This can be a problem when the completion setting wants to generate a candidate that actually ends with an isolated backslash.

I'll seek better solutions later.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants