Files
FastAnime/fastanime/libs/selectors/fzf/selector.py
2025-07-13 12:30:09 +03:00

64 lines
2.0 KiB
Python

import logging
import os
import shutil
import subprocess
from ....core.config import FzfConfig
from ..base import BaseSelector
logger = logging.getLogger(__name__)
class FzfSelector(BaseSelector):
def __init__(self, config: FzfConfig):
self.config = config
self.executable = shutil.which("fzf")
if not self.executable:
raise FileNotFoundError("fzf executable not found in PATH.")
os.environ["FZF_DEFAULT_OPTS"] = self.config.opts
# You can prepare default opts here from the config
def choose(self, prompt, choices, *, preview=None, header=None):
fzf_input = "\n".join(choices)
# Build command from base options and specific arguments
commands = []
commands.extend(["--prompt", f"{prompt.title()}: "])
if header:
commands.extend(["--header", header])
if preview:
commands.extend(["--preview", preview])
result = subprocess.run(
[self.executable, *commands],
input=fzf_input,
stdout=subprocess.PIPE,
text=True,
)
if result.returncode != 0:
return None
return result.stdout.strip()
def confirm(self, prompt, *, default=False):
choices = ["Yes", "No"]
default_choice = "Yes" if default else "No"
result = self.choose(prompt, choices, header=f"Default: {default_choice}")
return result == "Yes"
def ask(self, prompt, *, default=None):
# Use FZF's --print-query to capture user input
commands = []
commands.extend(["--prompt", f"{prompt}: ", "--print-query"])
result = subprocess.run(
[self.executable, *commands],
input="",
stdout=subprocess.PIPE,
text=True,
check=False,
)
# The output contains the selection (if any) and the query on the last line
lines = result.stdout.strip().splitlines()
return lines[-1] if lines else (default or "")