2019-02-22 07:48:05 -08:00
|
|
|
#!/usr/bin/python3
|
|
|
|
"""Fuzzy-find a file and check which package owns it.
|
|
|
|
|
|
|
|
Dependencies
|
|
|
|
============
|
|
|
|
* fzf
|
|
|
|
* mlocate
|
|
|
|
"""
|
|
|
|
|
|
|
|
import argparse
|
|
|
|
import subprocess
|
|
|
|
|
|
|
|
# ========== Constants ==========
|
|
|
|
# Commands
|
|
|
|
PACMAN_CMD = '/usr/bin/pacman'
|
|
|
|
FZF_CMD = '/usr/bin/fzf'
|
|
|
|
FZF_OPTS = ['--read0', '--select-1', '--exit-0', '--print0']
|
|
|
|
LOCATE_CMD = '/usr/bin/locate'
|
|
|
|
LOCATE_OPTS = ['--all', '--ignore-case', '--null']
|
|
|
|
LOCALE = 'utf-8'
|
|
|
|
|
|
|
|
|
|
|
|
# ========== Functions ==========
|
|
|
|
def run_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: str
|
|
|
|
"""
|
|
|
|
selected_file = subprocess.run([FZF_CMD] + FZF_OPTS,
|
|
|
|
input=files,
|
|
|
|
stdout=subprocess.PIPE).stdout
|
|
|
|
|
|
|
|
return selected_file.decode(LOCALE).strip('\x00')
|
|
|
|
|
|
|
|
|
|
|
|
def locate_files(patterns):
|
|
|
|
"""Use a locate-based program to locate files, then pass to fzf.
|
|
|
|
|
|
|
|
:param patterns: patterns to pass to locate
|
|
|
|
:type patterns: list
|
|
|
|
:returns: path of user-selected file
|
|
|
|
:rtype: bytes
|
|
|
|
"""
|
|
|
|
cmd = [LOCATE_CMD] + LOCATE_OPTS
|
|
|
|
cmd.extend(patterns)
|
|
|
|
|
|
|
|
return subprocess.run(cmd, capture_output=True).stdout
|
|
|
|
|
|
|
|
|
|
|
|
# ========== Main Script ==========
|
|
|
|
parser = argparse.ArgumentParser()
|
|
|
|
parser.add_argument('patterns',
|
|
|
|
nargs='+',
|
|
|
|
help='file pattern to search for')
|
|
|
|
|
|
|
|
args = parser.parse_args()
|
|
|
|
|
|
|
|
files = locate_files(args.patterns)
|
|
|
|
selected_file = run_fzf(files)
|
|
|
|
|
|
|
|
subprocess.run([PACMAN_CMD, '-Qo', selected_file])
|