46 lines
1.3 KiB
Python
Executable File
46 lines
1.3 KiB
Python
Executable File
"""
|
|
.. moduleauthor:: Eric Torres
|
|
.. module:: files-scripts.fzf
|
|
:synopsis: Helper functions for interacting with fzf
|
|
"""
|
|
# ========== Imports ==========
|
|
import shutil
|
|
import subprocess
|
|
|
|
import file_scripts.error as error
|
|
|
|
from pathlib import Path
|
|
|
|
# ========== Constants ==========
|
|
# ----- Commands -----
|
|
# Options: read null terminator, auto-select if one option, exit if no options, print null terminator
|
|
FZF_CMD = shutil.which("fzf")
|
|
FZF_OPTS = ["--read0", "--select-1", "--exit-0", "--print0"]
|
|
|
|
# ----- Misc. -----
|
|
LOCALE = "utf-8"
|
|
|
|
|
|
class FZFError(Exception):
|
|
pass
|
|
|
|
|
|
# ========== Functions ==========
|
|
def select_file_with_fzf(files):
|
|
"""Run fzf on a stream of searched files for the user to select.
|
|
|
|
:param files: stream of null-terminated files to read
|
|
:type files: bytes stream (stdout of a completed process)
|
|
:returns: selected file
|
|
:rtype: path-like object
|
|
:raises: FZFError if there was an error with fzf or no file was selected
|
|
"""
|
|
output = subprocess.run([FZF_CMD, *FZF_OPTS], input=files, stdout=subprocess.PIPE)
|
|
|
|
try:
|
|
output.check_returncode()
|
|
except subprocess.CalledProcessError as e:
|
|
raise FZFError(error.NO_FILE_SELECTED_MESSAGE) from e
|
|
else:
|
|
return Path(output.stdout.decode(LOCALE).strip("\x00"))
|