Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

-i for in-place edit #171

Open
gelisam opened this issue Nov 6, 2017 · 11 comments
Open

-i for in-place edit #171

gelisam opened this issue Nov 6, 2017 · 11 comments

Comments

@gelisam
Copy link
Owner

gelisam commented Nov 6, 2017

No description provided.

@gelisam gelisam changed the title -i for in-place edit -i for in-place edit Nov 6, 2017
@Rahel-A
Copy link

Rahel-A commented Mar 6, 2018

We'll be looking at this issue in this fork: https://github.com/lars-olsson/hawk/tree/master

@gelisam
Copy link
Owner Author

gelisam commented Mar 10, 2018

Any progress? Can I help with anything?

@Rahel-A
Copy link

Rahel-A commented Mar 10, 2018

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.

@Rahel-A
Copy link

Rahel-A commented Mar 10, 2018

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

@gelisam
Copy link
Owner Author

gelisam commented Mar 10, 2018

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.

@gelisam
Copy link
Owner Author

gelisam commented Mar 10, 2018

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?

@gelisam
Copy link
Owner Author

gelisam commented Mar 10, 2018

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?

@Rahel-A
Copy link

Rahel-A commented Mar 11, 2018

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.

@gelisam
Copy link
Owner Author

gelisam commented Mar 11, 2018

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"?

@gelisam
Copy link
Owner Author

gelisam commented Mar 11, 2018

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.

@gelisam
Copy link
Owner Author

gelisam commented Mar 11, 2018

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants