else/Toolbox/search.py
Ethan Dalool ece215dfc1 else
2017-03-30 15:56:12 -07:00

94 lines
2.7 KiB
Python

import argparse
import fnmatch
import os
import re
import sys
from voussoirkit import clipext
from voussoirkit import expressionmatch
from voussoirkit import safeprint
from voussoirkit import spinal
def search(
terms,
*,
case_sensitive=False,
do_expression=False,
do_glob=False,
do_regex=False,
inverse=False,
local_only=False,
match_any=False,
text=None,
):
def term_matches(text, term):
if not case_sensitive:
text = text.lower()
return (
(term in text) or
(do_regex and re.search(term, text)) or
(do_glob and fnmatch.fnmatch(text, term)) or
(do_expression and term.evaluate(text))
)
if not case_sensitive:
terms = [term.lower() for term in terms]
if do_expression:
terms = ' '.join(terms)
terms = [expressionmatch.ExpressionTree.parse(terms)]
anyall = any if match_any else all
if text is None:
walk = spinal.walk_generator(
depth_first=False,
recurse=not local_only,
yield_directories=True,
)
lines = ((filepath.basename, filepath.absolute_path) for filepath in walk)
else:
lines = text.splitlines()
for line in lines:
if isinstance(line, tuple):
(line, printout) = line
else:
printout = line
matches = anyall(term_matches(line, term) for term in terms)
if matches ^ inverse:
safeprint.safeprint(printout)
def search_argparse(args):
return search(
terms=args.search_terms,
case_sensitive=args.case_sensitive,
do_glob=args.do_glob,
do_regex=args.do_regex,
inverse=args.inverse,
local_only=args.local_only,
match_any=args.match_any,
text=args.text if args.text is None else clipext.resolve(args.text),
)
def main(argv):
parser = argparse.ArgumentParser()
parser.add_argument('search_terms', nargs='+', default=None)
parser.add_argument('--any', dest='match_any', action='store_true')
parser.add_argument('--case', dest='case_sensitive', action='store_true')
parser.add_argument('--regex', dest='do_regex', action='store_true')
parser.add_argument('--glob', dest='do_glob', action='store_true')
parser.add_argument('--expression', dest='do_expression', action='store_true')
parser.add_argument('--local', dest='local_only', action='store_true')
parser.add_argument('--inverse', dest='inverse', action='store_true')
parser.add_argument('--text', dest='text', default=None)
parser.set_defaults(func=search_argparse)
args = parser.parse_args(argv)
args.func(args)
if __name__ == '__main__':
main(sys.argv[1:])