-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[Console] allow multiline responses to console questions #37683
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
[Console] allow multiline responses to console questions #37683
Conversation
Thanks for the PR. Is there any prior art on the topic where 3 |
Good questions. I cannot find any prior art for this pattern. I had thought that commitizen prompts the user in this way, but after testing again just now, it continues after a single newline character. Here is my use-case for this: I am working on a Conventional Commits plugin for CaptainHook. According to the Conventional Commits specification, "a commit body is free-form and MAY consist of any number of newline separated paragraphs." My goal is to prompt the user to enter a longer description (the body), allowing them to enter multiple paragraphs, bullet lists, etc. as part of the body. Originally, I thought to use 2 newlines (i.e., when a user is finished, they'd hit ENTER twice to continue to the next prompt), but this prevents the user from being able to create multiple paragraphs (with a single newline between them). The only solution I could think of was to assume two empty newlines meant that the user is ready to continue. This happens when the user hits ENTER three times in a row. Another option the user may take is to use Ctrl+D (on Unix) or Ctrl+Z (on Windows) to send the end-of-transmission control character, which I have documented this in symfony/symfony-docs#14002, but I agree that hitting ENTER 3 times or using Ctrl+D or Ctrl+Z may not be intuitive or easily discoverable. I'm open to other ideas for how to handle this. |
The symfony maker bundle, for example, suffix the question with an hint. And I think ppl know/are familiar with this DX. https://github.com/symfony/maker-bundle/blob/master/src/Maker/MakeEntity.php#L288 Maybe it is possible, when the That being said, I got no opinion on the exit keyboard shortcut(s) (as we can not use Return) :) |
The keyboard shortcuts I mentioned work by default (since |
What about removing the 3-enter case, and always display the hint about CTRL+D/Z? |
I'd be fine with that. Is the hint something that the helper can add by default, or is it something that all implementors need to append to their question text? |
The helper should add the hint ideally to me. |
Updated to include feedback. The build failure does not appear related to this PR; the master branch is also failing. |
Here's a simple console script to show this working: https://gist.github.com/ramsey/1b7b19356b7e542d3c885ed4f82e4d82 |
Multiline support PR is awaiting merge: symfony/symfony#37683
Thank you @ramsey. |
… (ramsey) This PR was merged into the master branch. Discussion ---------- [Console] allow multiline responses to console questions Documentation for new multiline responses feature proposed in symfony/symfony#37683 Commits ------- e82b66b [Console] allow multiline responses to console questions
I opened a PR : #38345 |
…'t close input (ramsey) This PR was squashed before being merged into the 5.2-dev branch (closes #38351). Discussion ---------- [Console] clone stream on multiline questions so EOT doesn't close input | Q | A | ------------- | --- | Branch? | master | Bug fix? | yes | New feature? | no | Deprecations? | no | Tickets | N/A | License | MIT | Doc PR | N/A This fixes a bug in the multiline question feature that was introduced in #37683. Today, @epitre commented on #37683 (comment): > If I ask a question AFTER using the multiline option in a previous question, then it seems that the ctrl+d is kind of saved, and the command gets aborted. I'm honestly not sure how I missed this while working on #37683, since I was testing it with multiple questions, but I think it might have resulted from some of the back-and-forth and the lack of ability to effectively test the EOT character from a unit test. The solution was to _clone_ the input stream resource and use the clone to read the multiline input and capture the EOT byte. In this way, the primary input stream is not closed by the EOT. This is similar to @epitre's solution in #38345, but I'm using the `uri` and `mode` from `stream_get_meta_data()` to create the new stream, and if the existing stream has any data and is seekable and writable (like the streams used in the tests), I add the data to the clone and seek to the same offset. I've ensured that this solution works on a question that is in the middle of a series of other questions, and I've tested in on *nix and Windows. I've also improved the tests for multiline questions. While I'm unable to test (with a unit test) that an EOT character effectively stops reading from STDIN while continuing to the next question and prompt, I feel confident that the tests here provide sufficient coverage. Commits ------- ec688a3 [Console] clone stream on multiline questions so EOT doesn't close input
…'t close input (ramsey) This PR was squashed before being merged into the 5.2-dev branch (closes #38351). Discussion ---------- [Console] clone stream on multiline questions so EOT doesn't close input | Q | A | ------------- | --- | Branch? | master | Bug fix? | yes | New feature? | no | Deprecations? | no | Tickets | N/A | License | MIT | Doc PR | N/A This fixes a bug in the multiline question feature that was introduced in #37683. Today, @epitre commented on symfony/symfony#37683 (comment): > If I ask a question AFTER using the multiline option in a previous question, then it seems that the ctrl+d is kind of saved, and the command gets aborted. I'm honestly not sure how I missed this while working on #37683, since I was testing it with multiple questions, but I think it might have resulted from some of the back-and-forth and the lack of ability to effectively test the EOT character from a unit test. The solution was to _clone_ the input stream resource and use the clone to read the multiline input and capture the EOT byte. In this way, the primary input stream is not closed by the EOT. This is similar to @epitre's solution in symfony/symfony#38345, but I'm using the `uri` and `mode` from `stream_get_meta_data()` to create the new stream, and if the existing stream has any data and is seekable and writable (like the streams used in the tests), I add the data to the clone and seek to the same offset. I've ensured that this solution works on a question that is in the middle of a series of other questions, and I've tested in on *nix and Windows. I've also improved the tests for multiline questions. While I'm unable to test (with a unit test) that an EOT character effectively stops reading from STDIN while continuing to the next question and prompt, I feel confident that the tests here provide sufficient coverage. Commits ------- ec688a361e [Console] clone stream on multiline questions so EOT doesn't close input
By default, the question helper stops reading user input when it receives a newline character (i.e., when the user hits
ENTER
once). However, with this feature, developers may specify that the response to a question should allow multiline answers by passingtrue
tosetMultiline()
.Multiline questions stop reading user input after receiving three newline characters in a row (i.e., the user hits
ENTER
three times) or an end-of-transmission control character (Ctrl-D
on Unix systems orCtrl-Z
on Windows).If a user enters a newline character without input, control is returned to the question class, where the input may be validated to prompt the user again (in the case of a required question), or control may be passed along to the rest of the script.