Skip to content

Fix #1369 Print a newline after interpreted commands #3911

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

Merged
merged 3 commits into from
May 9, 2018

Conversation

benkobalog
Copy link
Contributor

Keeping only one newline for Unit values if there are more of them in a command.

Copy link
Member

@dottybot dottybot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello, and thank you for opening this PR! 🎉

All contributors have signed the CLA, thank you! ❤️

Have an awesome day! ☀️

@@ -272,7 +272,7 @@ class ReplDriver(settings: Array[String],
(
typeAliases.map("// defined alias " + _.symbol.showUser) ++
defs.map(rendering.renderMethod) ++
vals.map(rendering.renderVal).flatten
vals.map(rendering.renderVal).distinct
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How is scala> print("Hello"); print("Hello") rendered with this fix?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

scala>  print("Hello"); print("Hello") 
HelloHello
scala>  

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about val foo = 2; (); val bar = 3?

Copy link
Contributor Author

@benkobalog benkobalog Jan 25, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

scala> val foo = 2; (); val bar = 3 
val foo: Int = 2

val bar: Int = 3
scala>  

The sequence keeps the order. Maybe Units could be dropped if there's something else in the renderVal sequence.
That would produce this:

scala> print("Hello"); val foo = 2; (); val bar = 3 
Helloval foo: Int = 2
val bar: Int = 3
scala> 

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, something like:

val renderedVals =
  vals.flatMap(rendering.renderVal)

val toRender =
  typeAliases.map("// defined alias " + _.symbol.showUser) ++
  defs.map(rendering.renderMethod) ++
  renderedVals

toRender.foreach(str => out.println(SyntaxHighlighting(str)))

if (renderedVals.isEmpty && vals.nonEmpty)
  out.println() // prints new line for side-effectful unit value (see #1369)

I would also be fine with a solution, that prints an additional new line for each command interpreted.

Copy link
Contributor Author

@benkobalog benkobalog Jan 25, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, this Unit based solution has many edge cases.

So something like this at ReplDriver.scala:195?

      case parsed: Parsed if parsed.trees.nonEmpty =>
        val newState = compile(parsed)
          .withHistory(parsed.sourceCode :: state.history)
          .newRun(compiler, rootCtx)
        out.println()
        newState

@benkobalog benkobalog changed the title Fix #1369 Print a newline for Unit values Fix #1369 Print a newline after interpreted commands Jan 26, 2018
@allanrenucci
Copy link
Contributor

Can you add back the test case? Otherwise LGTM

@benkobalog
Copy link
Contributor Author

Sure. However I just realised that in this from it's not useful because end of line whitespaces are cut out by this function. So I will add it as a "whitespace sensitve" test, probably in a different folder.

@allanrenucci
Copy link
Contributor

You can rebase to fix the CI failures

@benkobalog
Copy link
Contributor Author

Thank you!

@allanrenucci
Copy link
Contributor

Can you give a motivation for changing the testing framework? We don't really want to test that the repl prints a new line or not but rather make sure that the repl is not going to eat the output of a command.

Do you need to modify the testing framework to test something like:

scala> print("foo")
foo

If not, I'd rather keep the testing framework at it is.

@benkobalog
Copy link
Contributor Author

If I do something like this:

scala> print("foo")
foo
scala> 1
val res0: Int = 1

It still doesn't work in the tests with this fix.
Maybe because the print in the ScripedTests file prints to the console which I'm running sbt in and probably not to the test output stream.
So I get this:

[info] Test dotty.tools.repl.ScriptedTests.replTests started
foo[info] Test dotty.tools.repl.ScriptedTests.typePrinterTests started

So I'm not sure how to test this.

@allanrenucci
Copy link
Contributor

allanrenucci commented Jan 29, 2018

Nice catch! The output of print("foo") is not captured by the repl test. I'll look into this issue

@allanrenucci
Copy link
Contributor

allanrenucci commented Jan 29, 2018

I have opened #3940, which should solve this problem

@allanrenucci
Copy link
Contributor

allanrenucci commented Jan 30, 2018

#3940 has been merged. Can you rebase and append a test to https://github.com/dotty-staging/dotty/blob/f068bea112b7f3a9274a61ee5ea3f845e2c11c39/compiler/test-resources/repl/outputStream:

scala> print("foo") // see #1369
foo

@benkobalog
Copy link
Contributor Author

benkobalog commented Jan 30, 2018

Now the prints go to the proper place (after adding a print function to the ReplTest class).
However the test is still not good :( It passes regardless I add the newline after commands or not.

The reason seems to be that we don't call prompt printing in the tests, only the interpret function.
In the function runUntilQuit readLine() eventually calls the prompt string printing which overwrites the previously printed text, causing the bug we want to fix here. But in the tests we only call interpret (which comes later in runUntilQuit()).

@benkobalog
Copy link
Contributor Author

benkobalog commented Jan 30, 2018

Currently I don't have a better idea than doing something like

echo 'print("asd") ' | ./bin/dotr

And checking the output. But it's probably too slow.
Technically we could do the same thing inside jvm, but StoringPrintStream should work the same way as a terminal does for the relevant features (at least deleting characters should work, not sure if there are other features).
Is this something worth doing or do you have a better idea?

@smarter
Copy link
Member

smarter commented May 8, 2018

@allanrenucci Could you have another look at this PR and see what can be done to get it merged? Thanks.

@allanrenucci
Copy link
Contributor

@benkobalog I dropped the commit for the REPL tests. I'll fix them in a separate PR

@allanrenucci allanrenucci merged commit be25213 into scala:master May 9, 2018
@allanrenucci
Copy link
Contributor

Sorry for the late review. Thanks @benkobalog 🎉

@benkobalog benkobalog deleted the fix-#1369 branch May 10, 2018 09:14
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

Successfully merging this pull request may close these issues.

4 participants