util.py: implemented rofi wrapper

This commit is contained in:
dogeystamp 2023-07-23 18:20:34 -04:00
parent 5b8742f7c0
commit 482d443314
Signed by: dogeystamp
GPG Key ID: 7225FE3592EFFA38

58
util.py Normal file
View File

@ -0,0 +1,58 @@
import subprocess
from dataclasses import dataclass
from typing import Optional
@dataclass
class RofiResult:
"""Data returned from Rofi.
Attributes
----------
index
Index within entries of the selected entry.
`None` if nothing was selected.
value
Selected entry's string value.
`None` if the value is not in the list or nothing was selected.
custom_bind
ID of custom bind used to select entry. None if no custom bind was used.
"""
index: Optional[int]
value: str
custom_bind: Optional[int]
def rofi(entries: list[str], prompt: str="> ", fuzzy=True, extra_args=[]) -> Optional[RofiResult]:
"""Start a Rofi prompt.
Returns
-------
None if the prompt was cancelled, or a `RofiResult`.
"""
args = ["rofi", "-dmenu", "-sep", "\\0"]
args += ["-p", prompt]
if fuzzy:
args += ["-matching", "fuzzy"]
args += extra_args
ret = RofiResult(None, "", None)
res = subprocess.run(args, input="\0".join(entries), stdout=subprocess.PIPE, text=True)
match res.returncode:
case 0:
pass
case 1:
return None
case x if x >= 10 and x <= 28:
ret.custom_bind = x - 9
case _ as retc:
raise RuntimeError(f"Rofi returned an unexpected return code `{retc}`.")
ret.value = res.stdout.strip()
try:
ret.index = entries.index(ret.value)
except ValueError:
pass
return ret