mvdan/gogrep

add composability of commands

Closed this issue · 3 comments

mvdan commented

What gogrep does at the moment is find all occurences of an expression. Let's call this the x command.

gogrep has an implicit print command at the end, which we will ignore - it will stay implicit in the input.

It would be useful to be able to compose these commands. For example, I could say:

gogrep '<x> if $_ { $*_ } <x> continue'

This would find all continue statements inside an if.

Other commands would also be helpful. For example:

  • Filter out nodes with zero matches of expression (g)
  • Filter out nodes with non-zero matches of expression (v)

Then one could find all naked loops that never break with:

gogrep '<x> for { $*_ } <v> break'

This composability was initially suggested by @rogpeppe, borrowing from the structural regexes in Acme. More info at http://doc.cat-v.org/bell_labs/structural_regexps/se.pdf

Reusing these names seems fine since they're short. They are also intuitive since they're similar to what one is used to in programs like vim and sed (and acme itself, of course).

mvdan commented

If I recall correctly, @rogpeppe prefers flags (i.e. gogrep -x 'expr' -v 'expr') since it already splits each string, removing part of the complexity.

mvdan commented

If we are to use flags, I would swap the args around, like:

gogrep pkgs [-cmd expr ...]

Then, the simple gogrep expr would become gogrep . -x expr, and the other combos would follow naturally.

mvdan commented

@rogpeppe this is now done. The code changes were easy once I had made the groundwork for them. Adding more commands should be fairly easy - the way they are now, they take a []ast.Node and return an []ast.Node. x uses that to generate any number of nodes, and g and v use it to return a filtered list.

I think the interface should be powerful enough, as long as they all simply go forward.

If you come up with new commands we should add, or any other feature or bug, please open another issue.