feat:switch to pure fzf for menus

This commit is contained in:
Benex254
2024-08-05 09:47:00 +03:00
parent d1fb3e16c9
commit c467645fb0
4 changed files with 246 additions and 0 deletions

View File

View File

@@ -0,0 +1,137 @@
import logging
import os
import shutil
import subprocess
import sys
from typing import Callable, List
from art import text2art
from rich import print
from ... import PLATFORM
from .config import FZF_DEFAULT_OPTS, FzfOptions
logger = logging.getLogger(__name__)
# fzf\
# --info=hidden \
# --layout=reverse \
# --height=100% \
# --prompt="Select Channel: " \
# --header="$fzf_header" \
# --preview-window=left,50%\
# --bind=right:accept \
# --expect=shift-left,shift-right\
# --tabstop=1 \
# --no-margin \
# +m \
# -i \
# --exact \
def clear():
if PLATFORM == "Windows":
os.system("cls")
else:
os.system("clear")
class FZF:
if not os.getenv("FZF_DEFAULT_OPTS"):
os.environ["FZF_DEFAULT_OPTS"] = FZF_DEFAULT_OPTS
FZF_EXECUTABLE = shutil.which("fzf")
default_options = [
"--cycle",
"--info=hidden",
"--layout=reverse",
"--height=100%",
"--bind=right:accept",
"--no-margin",
"+m",
"-i",
"--expect=shift-left,shift-right",
"--exact",
"--tabstop=1",
"--preview-window=left,35%,wrap",
"--wrap",
]
def _with_filter(self, command: str, work: Callable) -> List[str]:
try:
process = subprocess.Popen(
command,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
text=True,
shell=True,
)
except subprocess.SubprocessError as e:
print(f"Failed to start subprocess: {e}", file=sys.stderr)
return []
original_stdout = sys.stdout
sys.stdout = process.stdin
try:
work()
if process.stdin:
process.stdin.close()
except Exception as e:
print(f"Exception during work execution: {e}", file=sys.stderr)
finally:
sys.stdout = original_stdout
output = []
if process.stdout:
output = process.stdout.read().splitlines()
process.stdout.close()
return output
def _run_fzf(self, commands: list[FzfOptions], _fzf_input) -> str:
fzf_input = "\n".join(_fzf_input)
if not self.FZF_EXECUTABLE:
raise Exception("fzf executable not found")
result = subprocess.run(
[self.FZF_EXECUTABLE, *commands],
input=fzf_input,
stdout=subprocess.PIPE,
text=True,
)
if not result or result.returncode != 0 or not result.stdout:
print("sth went wrong:confused:")
input("press enter to try again...")
clear()
return self._run_fzf(commands, _fzf_input)
clear()
return result.stdout.strip()
def run(
self,
fzf_input: list[str],
prompt: str,
header: str,
preview: str | None = None,
) -> str:
_commands = [
*self.default_options,
"--header",
text2art(header),
"--header-first",
"--prompt",
prompt.title(),
] # pyright:ignore
if preview:
_commands.append(f"--preview={preview}")
return self._run_fzf(_commands, fzf_input) # pyright:ignore
fzf = FZF()
if __name__ == "__main__":
fzf.run([*os.listdir(), "exit"], "Prompt: ", "Header", preview="bat {}")

View File

@@ -0,0 +1,90 @@
from typing import Literal
FZF_DEFAULT_OPTS = """
--color=fg:#d0d0d0,fg+:#d0d0d0,bg:#121212,bg+:#262626
--color=hl:#5f87af,hl+:#5fd7ff,info:#afaf87,marker:#87ff00
--color=prompt:#d7005f,spinner:#af5fff,pointer:#af5fff,header:#87afaf
--color=border:#262626,label:#aeaeae,query:#d9d9d9
--border="rounded" --border-label="" --preview-window="border-rounded" --prompt="> "
--marker=">" --pointer="" --separator="" --scrollbar=""
"""
fzf_options = {
"--height": "Specifies the height of fzf's interface as a percentage.",
"--layout": 'Specifies the layout of fzf (default: "default").',
"--reverse": "Search result list appears in reverse order.",
"--border": "Draws border around the finder.",
"--inline-info": "Displays finder info inline instead of at the bottom.",
"--header": "Prints a header at the top of the finder.",
"--header-lines": "Keeps the first N lines of the input at the top.",
"--prompt": 'Changes the prompt string (default: "> ").',
"--multi": "Enables multi-select with tab/shift-tab.",
"--preview": "Displays the output of the command as preview.",
"--preview-window": "Specifies the layout of the preview window.",
"--bind": "Binds key to action.",
"--color": "Specifies the color scheme.",
"--no-sort": "Disables the sorting of the result list.",
"--nth": 'Specifies the fields to be matched (default: "1").',
"--delimiter": "Specifies the delimiter to use when tokenizing.",
"--tiebreak": "Specifies the criteria to break ties.",
"--toggle-sort": "Toggles the sorting feature.",
"--with-nth": "Specifies the fields to be transformed.",
"--expect": "Specifies keys to expect for instant results.",
"--no-mouse": "Disables mouse interaction.",
"--margin": "Specifies the margin around the finder.",
"--no-hscroll": "Disables horizontal scrolling.",
"--no-bold": "Disables bold text.",
"--tabstop": "Specifies the number of spaces for a tab.",
"--cycle": "Cycles through the result list.",
"--phony": "Disables searching and forces all items to be shown.",
"--filepath-word": "Matches by the filename only.",
"--info": "Specifies where to display finder info.",
"--jump-labels": "Specifies the labels for jump and select mode.",
"--history": "Specifies the history file for the finder.",
"--history-size": "Specifies the size of the history.",
"--disabled": "Starts the finder in disabled mode.",
"--no-unicode": "Disables Unicode characters in fzf.",
"--separator": "Specifies the separator for multi-select.",
"--select-1": "Automatically selects if only one match.",
"--exit-0": "Exits with status 0 if there's no match.",
}
FzfOptions = Literal[
"--height",
"--layout",
"--reverse",
"--border",
"--inline-info",
"--header",
"--header-lines",
"--prompt",
"--multi",
"--preview",
"--preview-window",
"--color",
"--no-sort",
"--nth",
"--delimiter",
"--tiebreak",
"--toggle-sort",
"--with-nth",
"--expect",
"--no-mouse",
"--margin",
"--no-hscroll",
"--no-bold",
"--tabstop",
"--cycle",
"--phony",
"--info",
"--jump-labels",
"--history",
"--history-size",
"--bind",
"--disabled",
"--no-unicode",
"--separator",
"--select-1",
"--exit-0",
]

View File

@@ -0,0 +1,19 @@
preview_anime_search = 'hght=$(($FZF_PREVIEW_COLUMNS/2 +2));\
i=$(echo {}|sed "s/\\t.*$//g");\
echo $i>$HOME/.cache/magic-tape/search/channels/index.txt;\
TITLE="$(cat $HOME/.cache/magic-tape/search/channels/titles.txt|head -$i|tail +$i)";\
if [[ "$IMAGE_SUPPORT" != "none" ]]&&[[ "$IMAGE_SUPPORT" != "chafa" ]];then ll=0;while [ $ll -le $(($hght/2 - 2)) ];do echo "";((ll++));done;fi;\
ll=1; echo -ne "\x1b[38;5;241m"; while [ $ll -le $FZF_PREVIEW_COLUMNS ];do echo -n -e "";((ll++));done;echo -n -e "$normal";\
if [[ "$TITLE" == "Previous Page" ]];then draw_preview $(($hght/3)) 1 $(($FZF_PREVIEW_COLUMNS/2)) $(($FZF_PREVIEW_COLUMNS/2)) $HOME/.cache/magic-tape/png/previous.png;\
elif [[ "$TITLE" == "Next Page" ]];then draw_preview $(($hght/3)) 1 $(($FZF_PREVIEW_COLUMNS/2)) $(($FZF_PREVIEW_COLUMNS/2)) $HOME/.cache/magic-tape/png/next.png;\
elif [[ "$TITLE" == "Abort Selection" ]];then draw_preview $(($hght/3)) 1 $(($FZF_PREVIEW_COLUMNS/2)) $(($FZF_PREVIEW_COLUMNS/2)) $HOME/.cache/magic-tape/png/abort.png;\
else draw_preview $(($hght/3)) 1 $(($FZF_PREVIEW_COLUMNS/2)) $(($FZF_PREVIEW_COLUMNS/2)) $HOME/.cache/magic-tape/jpg/"$(cat $HOME/.cache/magic-tape/search/channels/ids.txt|head -$i|tail +$i)".jpg;fi;\
echo -e "\n""$Yellow""$TITLE""$normal"|fold -w $FZF_PREVIEW_COLUMNS -s;\
ll=1; echo -ne "\x1b[38;5;241m"; while [ $ll -le $FZF_PREVIEW_COLUMNS ];do echo -n -e "";((ll++));done;echo -n -e "$normal";\
if [[ $TITLE != "Abort Selection" ]]&&[[ $TITLE != "Next Page" ]]&&[[ $TITLE != "Previous Page" ]];\
then SUBS="$(cat $HOME/.cache/magic-tape/search/channels/subscribers.txt|head -$i|tail +$i)";\
echo -e "\n"$Green"Subscribers: ""$Cyan""$SUBS""$normal";\
ll=1; echo -ne "\x1b[38;5;241m"; while [ $ll -le $FZF_PREVIEW_COLUMNS ];do echo -n -e "";((ll++));done;echo -n -e "$normal";\
DESCRIPTION="$(cat $HOME/.cache/magic-tape/search/channels/descriptions.txt|head -$i|tail +$i)";\
echo -e "\n\x1b[38;5;250m$DESCRIPTION"$normal""|fold -w $FZF_PREVIEW_COLUMNS -s; \
fi;'