Coverage for src/pyselector/menus/fzf.py: 100%
55 statements
« prev ^ index » next coverage.py v7.2.2, created at 2023-03-29 12:33 -0300
« prev ^ index » next coverage.py v7.2.2, created at 2023-03-29 12:33 -0300
1# fzf.py
2from __future__ import annotations
4import logging
5import shlex
6from typing import Iterable
7from typing import Optional
8from typing import Union
10from pyselector import helpers
11from pyselector.key_manager 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 not kwargs.pop("preview", None):
47 args.append("--no-preview")
49 if kwargs.get("height"):
50 args.extend(shlex.split(f"--height {kwargs.pop('height')}"))
52 if prompt:
53 args.extend(["--prompt", prompt])
55 if multi_select:
56 args.append("--multi")
58 # FIX: rethink keybinds for FZF
59 log.debug("keybinds are disabled")
60 for key in self.keybind.all_registered:
61 args.extend(shlex.split(f"--bind='{key.bind}:{key.action}'"))
62 if not key.hidden:
63 header.append(f"Use {key.bind} {key.description}")
65 if kwargs:
66 for arg, value in kwargs.items():
67 log.debug("'%s=%s' not supported", arg, value)
69 if header:
70 mesg = "\n".join(msg.replace("\n", " ") for msg in header)
71 args.extend(shlex.split(f"--header '{mesg}'"))
73 return args
75 def prompt(
76 self,
77 items: Optional[Iterable[Union[str, int]]] = None,
78 case_sensitive: bool = None,
79 multi_select: bool = False,
80 prompt: str = "PySelector> ",
81 **kwargs,
82 ) -> tuple[Union[str, list[str]], int]:
83 if not items:
84 items = []
86 args = self._build_command(case_sensitive, multi_select, prompt, **kwargs)
87 selection, code = helpers._execute(args, items)
89 if multi_select:
90 return helpers.parse_multiple_bytes_lines(selection), code
91 return helpers.parse_bytes_line(selection), code