Coverage for src/pyselector/menus/fzf.py: 87%
54 statements
« prev ^ index » next coverage.py v7.2.2, created at 2023-03-24 11:53 -0300
« prev ^ index » next coverage.py v7.2.2, created at 2023-03-24 11:53 -0300
1# fzf.py
3import logging
4import shlex
5import warnings
6from typing import Iterable
7from typing import Optional
8from typing import Union
10from pyselector import helpers
11from pyselector.interfaces import KeyManager
13log = logging.getLogger(__name__)
16class Fzf:
17 def __init__(self) -> None:
18 self.name = "fzf"
19 self.url = "https://github.com/junegunn/fzf"
20 self.keybind = KeyManager()
22 @property
23 def command(self) -> str:
24 return helpers.check_command(self.name, self.url)
26 def _build_command(
27 self,
28 case_sensitive,
29 multi_select,
30 prompt,
31 **kwargs,
32 ) -> list[str]:
33 header: list[str] = []
34 args = shlex.split(self.command)
36 if case_sensitive is not None:
37 args.append("+i" if case_sensitive else "-i")
39 if kwargs.get("mesg"):
40 header.extend(shlex.split(f"'{kwargs.pop('mesg')}'"))
42 if kwargs.get("cycle"):
43 kwargs.pop("cycle")
44 args.append("--cycle")
46 if kwargs.get("preview") is not None:
47 preview = kwargs.pop("preview")
48 if not preview:
49 args.append("--no-preview")
51 if prompt:
52 args.extend(["--prompt", prompt])
54 if multi_select:
55 args.append("--multi")
57 for key in self.keybind.list_registered:
58 args.extend(shlex.split(f"--bind='{key.bind}:{key.action}'"))
59 if not key.hidden:
60 header.append(f"Use {key.bind} {key.description}")
62 if kwargs:
63 for arg, value in kwargs.items():
64 warnings.warn(UserWarning(f"'{arg}={value}' not supported"))
66 if header:
67 mesg = "\n".join(msg.replace("\n", " ") for msg in header)
68 args.extend(shlex.split(f"--header '{mesg}'"))
70 return args
72 def prompt(
73 self,
74 items: Optional[Iterable[Union[str, int]]] = None,
75 case_sensitive: bool = None,
76 multi_select: bool = False,
77 prompt: str = "PySelector> ",
78 **kwargs,
79 ) -> tuple[Union[str, list[str]], int]:
80 if not items:
81 items = []
83 args = self._build_command(case_sensitive, multi_select, prompt, **kwargs)
84 selection, code = helpers._execute(args, items)
86 if multi_select:
87 return helpers.parse_multiple_bytes_lines(selection), code
88 return helpers.parse_bytes_line(selection), code