** PLEASE BE AWARE THIS IS ALPHA SOFTWARE AND NOT ONLY WILL THE API CHANGE BUT IT WILL PROBABLY EAT YOUR CHILDREN. YOU HAVE BEEN WARNED. **
Lens based Haskell refactoring toolkit.
Study after study shows that the very best designers produce structures that are faster, smaller, simpler, clearer, and produced with less effort. The differences between the great and the average approach an order of magnitude.
- Fred Brooks
In all modes Refactorio traverses one or more files executing a
ByteString -> ByteString function on them. For a given file if the function does not change
the input then no output is logged for that file. If the function does change
the file then what happens next is dependent on the mode.
ByteString -> ByteString function definition will work, for example:
BS.reverse BS.take 1024 over convert Text.toUpper # or equivalently convert %~ Text.toUpper key "foo" . _Number *~ 3
Ask Mode (-a / --ask)
This is the default mode. In this mode Refactorio will show you the changes that it's about to make and prompt you on a file by file basis whether you want to accept the changes or not. If you accept, the file will be replaced, if not the file will be left intact (or you can 'Q'uit at any time).
Preview Mode (-p / --preview)
not touch any files. You can think of it sort of like a
In this mode Refactorio will just show all the changes that it would make, but
Review Mode (-r / --review)
In this mode Refactorio will make changes to all files without asking but will show the full set of changes as they are made.
Modify Mode (-m / --modify)
This is basically a
--quiet style mode that makes all changes without
confirmation and just reports which files changed with no further details.
Search Mode (-s / --search)
This is a special mode which currently only works with
haskell-src-exts(-prisms) which provide
SrcSpanInfos which represent the
portion of the source code that a given feature occupies. This mode can be
easily made to work with any other lenses that can provide access to similar
information and we are exploring ways to broaden it's usefulness further.
Here are a few examples to whet your appetite. For more see examples.
"Upper case the string values of the array found under 'quiz.sport.q1.options'."
YAML (same operators):
"Multiply the value of the key 'version' by 32."
TODO: Find a good way to deal with HTML. (problems with each of `hexpat-lens`, `hexml-lens`, `xml-html-conduit-lens` and `xml-lens`)
C'mon, you've never needed to "find all the authors with names longer than 15 characters and then sort all of the letters in their name that are above 'm' in place?" Pshaw.
Drop regex's in anywhere you like, eg. "uppercase and reverse the characters in the value of the JSON object at this key that match this regular expression":
Reach inside eg. gzipped files and do what you gotta do:
Example is temporarily unavailable, but goes something like:
refactorio -t foo.json.gz --json 'convert . from Z.gzipped . from convert . key \"baz\" . _Number *~ 85'
The beginnings of
convertTo/convertFrom (along with
exist which can be used like so:
When types can be infered:
% refactorio --html -t /tmp/voltron/src 'convert %~ Text.toUpper'
When types have to be clarified:
% refactorio --html -t /tmp/voltron/src 'convertTo(a::LByteString).xml...name %~ Text.toUpper'
TODO: revamp after re-wiring
Try these on your projects:
refactorio --haskell _Module.biplate._ModuleName.end refactorio --haskell _Module.biplate._Int.end refactorio --haskell _Module.biplate._String.end refactorio --haskell _Module.biplate._FieldUpdate.end refactorio --haskell _Module.biplate._Frac.end refactorio --haskell '_Module.biplate._Int.filtered(odd.view target).end' refactorio --haskell '_Module.biplate._Int.filtered(even.view target).end' refactorio --haskell '_Module.biplate._Int.filtered((>10).view target).end'
There are more examples here.
For now the easiest way to get it working is to
stack install . in this
directory. Then commands like this should work:
refactorio --json 'key "foo" . key "bar" . _Number *~ 15' -t ./examples
cat Somefile.hs | refactorio -s --haskell _Module.biplate._ModuleName.end -
--target is a file or directory to process and can be outside
of the refactorio project root).
In addition to the general warning about this being alpha quality software, no work has been done on performance and in fact in some cases even reasonable performance has been sacrificed in the name of expediency.
In some places I've resorted to outright hacks, such as when parsing YAML by
reading it as YAML, writing it as JSON for processing it with
then converting it back.
In addition to being slow some of these tricks will do things like cause a file to be reformatted by the serialization round-trip even if your function doesn't make an actual semantic change.
Configurable Format-specific Preludes
Refactorio has a hardcoded set of qualified imports which you can find somewhere around here.
Currently the only unqualified import that Refactorio mandates is
Text.Regex.Quote which brings the
r QuasiQuoter into scope.
In addition Refactorio attempts to load a single "Prelude" which can bring
unqualified names into scope. Various lens packages for different formats have
conflicting imports (eg. _String in
lens-aeson and in
haskell-src-exts-prisms) so to avoid conflicts for now if you pass a "special
mode" flag (eg.
--json, etc) Refactorio will attempt to use
Refactorio.Prelude.Haskell, etc). If no
special mode is provided,
Refactorio.Prelude.Basic is used.