Skip to content

Instantly share code, notes, and snippets.

@washtubs
Last active September 9, 2018 16:29
Show Gist options
  • Save washtubs/eaaa7ab68915d5ec5cda59f6ef212e05 to your computer and use it in GitHub Desktop.
Save washtubs/eaaa7ab68915d5ec5cda59f6ef212e05 to your computer and use it in GitHub Desktop.
find git grep combiner
#compdef qry
#autoload
function msg() {
echo $@ > /dev/pts/6
}
function _qry() {
find_part=()
grep_part=()
local grep_mode
local offset
offset=0
grep_mode="false"
for w in $words; do
if [ $w = "--" ]; then
grep_mode="true"
elif [ $grep_mode = "false" ]; then
find_part=($find_part $w)
((offset++))
else
grep_part=($grep_part $w)
fi
done
if [ $CURRENT -le $offset ]; then
_find
else
# not sure how to mock this
#msg trying _grep $service
#service=grep words=$grep_parts _grep
fi
}
#!/usr/bin/env zsh
# scope considerations
# This is a file/content search/modify swiss army knife intended primarily for interactive use. programmatic usage should involve taking the translated command, and optimizing it manually before putting it in your script
# it's use cases are basically as follows
# search for files using criteria
# select content from files matching criteria
# modify files matching criteria in place (with safe gaurds)
#
# features:
# unifying output format using annot
# just a glorified wrapper script
# user defined safe gaurds to prevent from modifying files which, say, aren't tracked by git, or confine modifications to a directory.
#
# what it is not:
# it is not for file operations like rm, mv, cp etc. Although it's fileselect use case can be leveraged for this purpose.
# qry *only* looks at or acts on files where they are.
# it should not consult external files. all configurations should be optional, and be loaded into the interactive shell by sourcing
# qry can "print" it's env
# notes on possible rewrite:
# use annot. making it so we no longer depend on grep to produce the filename list
# contentselect
# you can choose between grep or pcre grep or maybe even awk
# fileselect
# git ls-files or find
# make it so they can be strung together
# find in addition to being an *almost* perfect wrapper, supports an additional flag to pass presets i.e. "-select authored_by dmilum3" or "-select is_git_repository" or "-select is_git_directory_recurs_submodules"
# select will basically find an entry called authored_by, figure out how many params it takes and expand the result to an array of find args
# presets can also be supported for contentselect
# defaults should be supported as well, as they currently are. but we should also be able to see them easily.
#
# contentmodify
# another possible thing would be to optionally swap out contentselection for contentmodify. but limit contentmodify so that it is not given a filename just the stdin content. it's stdout can then be used to modify the file
# but qry can do some checks, such as making sure the file is backed up or is tracked and isn't currently dirty.
# Considering some commands ONLY support inplace modify, we may HAVE to pass filenames for certain things. however, with the surrounding logic of making and restoring backups, and we can make an inplace command do a preview.
# The above feels rather out of scope. maybe it's not such a good idea. it *might* make since to have a file exec phase
#
# finally the resultant command should be optionally printed so they can be used on systems that do not support qry and annot
# the shell should support one-way translating the command on the command line in place. for example, you do some fancy file selection but you want to add a -exec to the resultant find command.
#
# add debug options on the end to support shorting out the different phases. like JUST do fileselect, or maybe if using contentmodify, make it only do contentselect
# change things contextually.
# dual find-grep wrapper for git files!
# run it inside a git repository and it will search down from where you are
# find is not a perfect wrapper, certain opts should be ignored, like -exec and -print, we want a subset of find that only prints filenames
# architecture:
# search use case:
# fileselect | repath
# fileselect | abspath | fileselect | repath
# contentselect use case:
# fileselect | repath | annot contentselect
# fileselect | repath | annot contentselect | qfix
# contentmodify use case:
# fileselect | repath | xargs safe_modify {} contentselect
# safe_modify:
# cat {} | contentselect > tmp
# if modifiable; then; mv tmp {}; else PICNIC; fi
# selectors should be compatible with sanity (this makes me think they should be functions that return strings OR be format strings. they should be able to stand on their own. they need to be convertible to fileselects)
function qry() {
local find_params
local grep_params
local find_root
local use_stdin=false
local seed_find=false
find_params=()
grep_params=()
# if the first arg is a file, assume it is the find root
# and we don't want to seed from stdin or git ls-files or
# anything like that
if [ ! -z "$1" ] && [ -e "$1" ]; then
find_root=$1
seed_find=true
shift
fi
while [[ ! -z $1 && $1 != "--" ]]; do
find_params+=$1
shift
done
if [[ ! -z $1 && $1 = "--" ]]; then
shift
fi
while [[ ! -z $1 && $1 != "--" ]]; do
grep_params+=$1
shift
done
while [[ ! -z $1 && $1 = "--" ]]; do
# use stdin instead of git
use_stdin=true
shift --
done
local git_params_default
local xargs_params_default
local find_params_default
local grep_params_default
git_params_default=(ls-files .)
xargs_params_default=(-P10 -n20 -I '{{}}')
find_params_default=('{{}}')
# I use pcre grep cause I'm an opinionated jackass
# VERY interesting...
# using color=auto apparently prevents grep from sending colored
# output to the pipe of another program. When I had it set to always,
# the colored output made the piped command fail.
grep_params_default=(--color=auto -H -n -P)
if $use_stdin; then
seed=(cat /dev/stdin)
else
seed=(git ${git_params_default})
fi
# TODO modify to accept files from stdin, so we can make piped calls
if $seed_find; then
find ${find_root} ${find_params_default} ${find_params} \
-exec grep ${grep_params_default} ${grep_params} '{}' \; \
2>/dev/null
elif [ -z "$grep_params" ]; then
${seed} | \
xargs ${xargs_params_default} find ${find_params_default} ${find_params} \
2>/dev/null
else
${seed} | \
xargs ${xargs_params_default} find ${find_params_default} ${find_params} \
-exec grep ${grep_params_default} ${grep_params} '{}' \; \
2>/dev/null
fi
}
#xargs ${xargs_params_default} find ${find_params_default} ${find_params} \
#-exec grep ${grep_params_default} ${grep_params} '{}' \; \
#2>/dev/null <&0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment