diff --git a/news/fix-bash-completion-equal-sign-arg.rst b/news/fix-bash-completion-equal-sign-arg.rst new file mode 100644 index 000000000..c3f2c61bd --- /dev/null +++ b/news/fix-bash-completion-equal-sign-arg.rst @@ -0,0 +1,23 @@ +**Added:** + +* + +**Changed:** + +* + +**Deprecated:** + +* + +**Removed:** + +* + +**Fixed:** + +* A trailing space no longer gets appended when tab-completing command arguments that involve equals signs. For example `dd sta` gets completed to `dd status=`, without a space space after the equals sign. + +**Security:** + +* diff --git a/tests/completers/test_bash_completer.py b/tests/completers/test_bash_completer.py index 002ff6042..667dcbb5d 100644 --- a/tests/completers/test_bash_completer.py +++ b/tests/completers/test_bash_completer.py @@ -179,3 +179,33 @@ def test_bash_completer_empty_prefix(): ) bash_completions, bash_lprefix = complete_from_bash(context) assert {"clean", "show"}.issubset(bash_completions) + + +@skip_if_on_darwin +@skip_if_on_windows +@pytest.mark.parametrize( + "command_context, completions, lprefix", + ( + # dd sta -> dd status= + ( + CommandContext(args=(CommandArg("dd"),), arg_index=1, prefix="sta"), + {"status="}, + 3, + ), + # date --da -> date --date= + ( + CommandContext(args=(CommandArg("date"),), arg_index=1, prefix="--da"), + {"--date="}, + 4, + ), + ), +) +def test_equal_sign_arg(command_context, completions, lprefix): + bash_completions, bash_lprefix = complete_from_bash( + CompletionContext(command_context) + ) + assert bash_completions == completions and bash_lprefix == lprefix + assert all( + isinstance(comp, RichCompletion) and not comp.append_space + for comp in bash_completions + ) # there should not be an appended space after the equal sign diff --git a/tests/test_path_completers.py b/tests/completers/test_path_completers.py similarity index 81% rename from tests/test_path_completers.py rename to tests/completers/test_path_completers.py index dfff0d553..0d6341b20 100644 --- a/tests/test_path_completers.py +++ b/tests/completers/test_path_completers.py @@ -63,6 +63,24 @@ def test_complete_path_when_prefix_is_raw_path_string( assert expected == out[0].pop() +def test_complete_path_ending_with_equal_sign(xession, completion_context_parse): + xession.env = { + "CASE_SENSITIVE_COMPLETIONS": True, + "GLOB_SORTED": True, + "SUBSEQUENCE_PATH_COMPLETION": False, + "FUZZY_PATH_COMPLETION": False, + "SUGGEST_THRESHOLD": 1, + "CDPATH": set(), + } + with tempfile.NamedTemporaryFile(suffix="=") as tmp: + prefix_file_name = tmp.name.replace("=", "") + prefix = prefix_file_name + line = f"ls {prefix}" + out = xcp.complete_path(completion_context_parse(line, len(line))) + expected = f"{tmp.name} " # has trailing space + assert expected == out[0].pop() + + @pytest.mark.parametrize("prefix", ("", "r", "p", "pr", "rp")) def test_path_from_partial_string(prefix): string = "hello" diff --git a/xonsh/completers/bash.py b/xonsh/completers/bash.py index 458ab2452..8d4d4e33f 100644 --- a/xonsh/completers/bash.py +++ b/xonsh/completers/bash.py @@ -4,7 +4,6 @@ import xonsh.platform as xp import xonsh.tools as xt from xonsh.built_ins import XSH from xonsh.completers.bash_completion import bash_completions -from xonsh.completers.path import _quote_paths from xonsh.completers.tools import RichCompletion, contextual_command_completer from xonsh.parsers.completion_context import CommandContext @@ -41,7 +40,6 @@ def complete_from_bash(context: CommandContext): env=env, paths=paths, command=command, - quote_paths=_quote_paths, line_args=args, opening_quote=opening_quote, closing_quote=closing_quote, diff --git a/xonsh/completers/bash_completion.py b/xonsh/completers/bash_completion.py index 461f6b719..682201589 100644 --- a/xonsh/completers/bash_completion.py +++ b/xonsh/completers/bash_completion.py @@ -186,7 +186,7 @@ def _bash_quote_paths(paths, start, end): start = end = _bash_quote_to_use(s) if os.path.isdir(_bash_expand_path(s)): _tail = slash - elif end == "": + elif end == "" and not s.endswith("="): _tail = space else: _tail = ""