Source code for xonsh.lib.completion_quoting
"""Shared helper for deciding whether a completion candidate needs
shell-quoting in xonsh.
Used by both the built-in path completer
(:mod:`xonsh.completers.path`) and the bash-completion bridge
(:mod:`xonsh.completers.bash_completion`), which historically carried
near-identical copies of this regex that drifted over time.
Pure-Python, no side effects on import — safe for standalone use, as
:mod:`xonsh.completers.bash_completion` requires.
"""
import os
import platform
import re
# Characters the xonsh parser would treat specially in a subprocess
# argument, verified by feeding ``ls fi<ch>le`` through
# ``CompletionContextParser``:
#
# whitespace, ``|`` ``;`` ``<`` ``>`` ``&`` — split the token
# ``(`` ``)`` ``[`` ``]`` ``{`` ``}`` ``,`` — grouping / glob syntax
# ``*`` ``?`` — glob wildcards
# `` ` `` ``$`` — command/var substitution
# ``"`` ``'`` — string boundaries
# ``#`` — comment
# ``%`` (Windows only) — env var reference
#
# The word boundaries catch ``and``/``or`` appearing as whole tokens,
# since those are xonsh keywords.
_PATTERN = re.compile(
r"""[\s`$\{\}\[\]\,\*\(\)"'\?&#|;<>"""
+ ("%" if platform.system() == "Windows" else "")
+ r"]|\band\b|\bor\b"
)
[docs]
def name_needs_quotes(name: str, sep: str | None = None) -> bool:
"""Return True if *name* would be mangled by the xonsh parser and
therefore needs to be wrapped in quotes when emitted as a completion.
Parameters
----------
name :
The candidate completion string (a path, an executable name, …).
sep :
The path separator the caller treats as safe (``os.sep`` on
POSIX, ``os.altsep`` in forced-POSIX mode on Windows). When a
backslash appears in *name* but *sep* is not backslash, the
backslash is a shell metacharacter and forces quoting. Defaults
to :data:`os.sep`.
"""
if sep is None:
sep = os.sep
if _PATTERN.search(name):
return True
return "\\" in name and sep != "\\"