fix: append space at the end of completions (#4611)

This commit is contained in:
Noorhteen Raja NJ 2021-12-23 18:27:37 +05:30 committed by GitHub
parent af06aa8311
commit cd57240237
Failed to generate hash of commit
3 changed files with 80 additions and 19 deletions

View file

@ -0,0 +1,27 @@
import pytest
@pytest.fixture
def fish_completer(tmpdir, xession, load_xontrib, fake_process):
"""vox Alias function"""
load_xontrib("fish_completer")
xession.env.update(
dict(
XONSH_DATA_DIR=str(tmpdir),
XONSH_SHOW_TRACEBACK=True,
)
)
fake_process.register_subprocess(
command=["fish", fake_process.any()],
# completion for "git chec"
stdout=b"""\
cherry-pick Apply the change introduced by an existing commit
checkout Checkout and switch to a branch""",
)
return fake_process
def test_fish_completer(fish_completer, check_completer):
assert check_completer("git", prefix="chec") == {"checkout", "cherry-pick"}

View file

@ -81,6 +81,27 @@ class CommandContext(NamedTuple):
else: else:
return f"{self.opening_quote}{self.prefix}" return f"{self.opening_quote}{self.prefix}"
@property
def command(self):
if self.args:
return self.args[0].raw_value
return None
@property
def words_before_cursor(self) -> str:
"""words without current prefix"""
return " ".join([arg.raw_value for arg in self.args[: self.arg_index]])
@property
def text_before_cursor(self) -> str:
"""full text before cursor including prefix"""
return self.words_before_cursor + " " + self.prefix
@property
def begidx(self) -> int:
"""cursor's position"""
return len(self.text_before_cursor)
class PythonContext(NamedTuple): class PythonContext(NamedTuple):
""" """

View file

@ -1,43 +1,56 @@
from xonsh.completers import completer from xonsh.completers import completer
from xonsh.completers.tools import ( from xonsh.completers.tools import RichCompletion, contextual_command_completer
RichCompletion, import os
contextual_command_completer,
get_filter_function,
)
import subprocess as sp import subprocess as sp
from xonsh.built_ins import XSH from xonsh.built_ins import XSH
from xonsh.parsers.completion_context import CommandContext from xonsh.parsers.completion_context import CommandContext
def create_rich_completion(line: str): def create_rich_completion(line: str, append_space=False):
line = line.strip() line = line.strip()
if "\t" in line: if "\t" in line:
cmd, desc = map(str.strip, line.split("\t", maxsplit=1)) cmd, desc = map(str.strip, line.split("\t", maxsplit=1))
else: else:
cmd, desc = line, "" cmd, desc = line, ""
# special treatment for path completions.
# not appending space even if it is a single candidate.
if cmd.endswith(os.pathsep):
append_space = False
return RichCompletion( return RichCompletion(
str(cmd), cmd,
description=str(desc), description=desc,
append_space=True, append_space=append_space,
) )
@contextual_command_completer @contextual_command_completer
def fish_proc_completer(ctx: CommandContext): def fish_proc_completer(ctx: CommandContext):
"""Populate completions using fish shell and remove bash-completer""" """Populate completions using fish shell and remove bash-completer"""
args = [arg.value for arg in ctx.args] + [ctx.prefix] if not ctx.args:
line = " ".join(args) return
args = ["fish", "-c", f"complete -C '{line}'"] line = ctx.text_before_cursor
script_lines = [
f"complete --no-files {ctx.command}", # switch off basic file completions for the executable
f"complete -C '{line}'",
]
args = ["fish", "-c", "; ".join(script_lines)]
env = XSH.env.detype() env = XSH.env.detype()
output = sp.check_output(args, env=env).decode() try:
filter_func = get_filter_function() output = sp.check_output(args, env=env).decode()
except Exception as ex:
print(f"Failed to get fish-completions: {ex}")
return
if output: if output:
for line in output.strip().splitlines(keepends=False): lines = output.strip().splitlines(keepends=False)
comp = create_rich_completion(line) # if there is a single completion candidate then maybe it is over
if filter_func(comp, ctx.prefix): append_space = len(lines) == 1
yield comp for line in lines:
comp = create_rich_completion(line, append_space)
yield comp
completer.add_one_completer("fish", fish_proc_completer, "<bash") completer.add_one_completer("fish", fish_proc_completer, "<bash")