Open gelisam opened 7 years ago
Any progress? Can I help with anything?
I'm currently trying to understand the api for OptionParser. Is there a way for the parser to not consume the arguments (so that the same argument could be used to create both the input and output spec.)
I'm trying to write my syntax is as follows:
hawk -i[suffix] "1+1" -f"file.txt"
The input spec consumes the file argument, which prevents output spec from retrieving the input file name.
A snippet of what I'm trying to do:
inputSpec :: (Functor m, Monad m)
⇒ CommonSeparators → OptionParserT HawkOption m InputSpec
inputSpec (rSep, fSep) = InputSpec ↥ source ⊛ format
where
source = do
file ← consumeLast Option.InputFile "" $ consumeNullable "" consumeString
η $ if null file
then UseStdin
else InputFile file
outputSpec :: (Functor m, Monad m)
⇒ CommonSeparators → OptionParserT HawkOption m OutputSpec
outputSpec (r, f) = OutputSpec ↥ sink ⊛ format
where
sink = do
backupSuffix ← consumeLast Option.InPlaceEdit "" $ consumeNullable "" consumeString
file ← consumeLast Option.InputFile "" $ consumeNullable "" consumeString
if null file
then if null backupSuffix
then η UseStdout
else fail "in-place edit requires input file"
else η $ OutputFile file $ file ⧺ backupSuffix
Is there a way for the parser to not consume the arguments
It would be possible to write a variants of consumeAll
, consumeLast
and consumeExtra
which observe but do not modify the state. I don't recommend it though.
so that the same argument could be used to create both the input and output spec
The --field-delimiter
and --record-delimiter
options are also used by both the input and the output spec. In parseArgs
, this is accomplished by first calling commonSeparators
to consume those two options before passing the result to both the input and the output specs. This is the approach I would recommend.
I'm trying to write my syntax is as follows:
hawk -i[suffix] "1+1" -f"file.txt"
Why -f
? Is there something wrong with hawk's current approach of always putting the file name after the expression if any?
A snippet of what I'm trying to do:
[...] if null file [...]
Is there a reason why you are using the empty string as a distinguished value instead of using a Maybe FilePath
?
Why -f? Is there something wrong with hawk's current approach of always putting the file name after the expression if any?
This was just helping me understand how to explicitly parse arguments. But it still seems like I might need it because I believe you can input a list of files? So I'd would like to just be able to work with single files for now.
Is there a reason why you are using the empty string as a distinguished value instead of using a Maybe FilePath?
Adding consumeNullable changes the type from Maybe String to String
The --field-delimiter and --record-delimiter options are also used by both the input and the output spec. In parseArgs, this is accomplished by first calling commonSeparators to consume those two options before passing the result to both the input and the output specs. This is the approach I would recommend.
Yeah this approach seems to work well for me, thanks! I'll post an update later.
I believe you can input a list of files?
No, that feature is not yet implemented, see #13 and #50. Currently you can only specify zero files, in which case you'll get stdin, or one file, in which case you'd get that file.
I wonder if using -i
with stdin should be an error, or if writing to stdout should be considered close enough to "modifying stdin in-place"?
Oh, and even if if was possible to use a list of files, I still don't think adding a -f
option would be necessary; instead, it would be an error to use -i
with more than one file.
Adding consumeNullable changes the type from Maybe String to String
Ah, you're right! I don't remember why I designed it that way, it looks like a mistake now.
We'll be looking at this issue in this fork: https://github.com/lars-olsson/hawk/tree/master