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

Wrap/nowrap when copying multiple lines ... SetConsoleMode? #9528

Closed
vefatica opened this issue Mar 18, 2021 · 21 comments
Closed

Wrap/nowrap when copying multiple lines ... SetConsoleMode? #9528

vefatica opened this issue Mar 18, 2021 · 21 comments
Labels
Needs-Tag-Fix Doesn't match tag requirements Needs-Triage It's a new issue that the core contributor team needs to triage at the next triage meeting

Comments

@vefatica
Copy link

How is the wrap/nowrap behavior when copying multiple lines handled? Is it controlable with SetConsoleMode?

Thanks!

@ghost ghost added Needs-Triage It's a new issue that the core contributor team needs to triage at the next triage meeting Needs-Tag-Fix Doesn't match tag requirements labels Mar 18, 2021
@DHowett
Copy link
Member

DHowett commented Mar 18, 2021

Applications what write off the end of the line force a wrap. You can disable "deferred EOL" with SetConsoleMode.

@DHowett DHowett closed this as completed Mar 18, 2021
@vefatica
Copy link
Author

Can you be more specific?

I select two lines with the mouse and copy with a right-click. They comprised output which reached the end of the first line and was continued on the next line. What determines how they will paste (anywhere) ... as a single line or as two lines with a CRLF between them?

@vefatica
Copy link
Author

Wasn't my question well-posed? Let me try a different way. Don't bother trying to reproduce this; it's apparently an anomaly of the shell I'm using. Here's a command and its output, both selected (left button drag) from a console's history.

image

When I copy (right-click) and paste into an editor, I get

image

What can lead to this ... the command not wrapped and the output wrapped after copy/paste?

@DHowett
Copy link
Member

DHowett commented Mar 18, 2021

Wasn't my question well-posed?

Try as I might, I have been unable to defeat the need for sleep. Your question will be processed in the order in which it was received.

@vefatica
Copy link
Author

Sorry about that! I'm noted for impatience. I can't be the only person who has grown accustomed to your attentiveness.

@DHowett
Copy link
Member

DHowett commented Mar 18, 2021

So! Wrapping.

Wrapping is a source of a bunch of issues for us.

In general, text is considered wrapped in the following circumstances.

  • Traditional Console Output
    • ENABLE_WRAP_AT_EOL_OUTPUT on: Text is written in the rightmost column.
      • The cursor automatically moves into the next row, and the previous row is considered wrapped.
    • ENABLE_WRAP_AT_EOL_OUTPUT | DISABLE_NEWLINE_AUTO_RETURN: Text is written in the rightmost column, and then another non-control character is written in the "deferred" position.
      • The first write moves the cursor "off the right edge", and the next character is placed on the next row.
      • Writing a newline in the "deferred" position does not cause a wrap, because it expresses intent to move to a new line.
  • VT Output
    • VT output behaves like ENABLE_WRAP_AT_EOL_OUTPUT | DISABLE_NEWLINE_AUTO_RETURN (only because it is recommended that you use both of these in addition to ENABLE_VIRTUAL_TERMINAL_PROCESSING, I think?)

Moving the cursor between writes breaks wrapping.

Some applications, especially when they draw the prompt themselves, explicitly hard-wrap their output. What's likely happening is that the input line is being sent as V:\>echo fooooooooo \n ooooo, and when the command is processed foooooooooooooo is being generated as a single screen write (subject to the rules above.)

I can't be the only person who has grown accustomed to your attentiveness.

😅 you're right

@DHowett
Copy link
Member

DHowett commented Mar 18, 2021

(Sorry -- edited the above to fix an out of order bullet that somewhat changes the meaning.)

@vefatica
Copy link
Author

Hmmm! I've been trying to figure out how to ...

WCHAR szString[] = L"************************************************\n";
// this will wrap
WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), szString, lstrlen(szString), &dwWrote, NULL);
// do something to the console mode
WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), szString, lstrlen(szString), &dwWrote, NULL);

... then copy all the output, paste it somewhere, and have one wrap and the other not wrap. No success yet; both wrap! Any ideas?

@DHowett
Copy link
Member

DHowett commented Mar 18, 2021

Nope, both of those will wrap. There is no console mode that will disable wrapping.

Sorry! 😄

@DHowett
Copy link
Member

DHowett commented Mar 18, 2021

Hard wrapping must be done by the application -- measure the screen, print hard-wrapped sections of line with newlines between the sections. That's also the way voted most likely to work with all other terminal emulators.

@zadjii-msft
Copy link
Member

FYI - we are also tracking an intermittent issue where sometimes the Terminal decides that a line that should have wrapped actually didn't. We're tracking that broadly in #5800 and more specifically in #6901. I haven't the damndest clue what causes that, but if you could get a specific repro for it, then I could fix it and make a test ☺️

@vefatica
Copy link
Author

(#6901) I can repro this much. TYPE the file in CMD (or TCC) in WT ... copy the wrapped line and paste into notepad ... result: one line.

SSH (in WT) to localhost (no WSL involved) ... TYPE the file in the SSH session ... copy the wrapped line and paste into notepad ... result: several lines.

But I can't (as in #6901) get a different (single line) result after resizing WT.

[TCC is my SSH shell.]

@DHowett
Copy link
Member

DHowett commented Mar 18, 2021

SSH uses an old version of ConPTY 😄 which did not support line wrapping!

@vefatica
Copy link
Author

SSH uses an old version of ConPTY 😄 which did not support line wrapping!

I'm not sure what you mean. SSH is using the usual conhost.exe on both ends and mine seems pretty good at line wrapping.

@DHowett
Copy link
Member

DHowett commented Mar 19, 2021

When you SSH to a Windows machine, it hosts the console application using the version of conhost on that machine. That version of conhost contains whatever version of ConPTY existed at the time. The old version of ConPTY¹ cannot properly communicate which lines "wrapped" when it reproduces the screen content. The old version of ConPTY¹ will therefore emit any lines, wrapped or not, with a newline at the end of them. They will appear to be "hard-wrapped" from the perspective of any recipient.

¹ I promise you are using an old version of conpty if you're SSHing to a Windows machine.

@vefatica
Copy link
Author

I'm SSHing to localhost and I see this. Both conhosts are c:\windows\system32\conhost.exe. I just want to understand.

Start  Time            Pid   PPid       CPU(s)     WS(M)  Name
--------------------------------------------------------------------------------
03/19  12:04:46.178   6428   9536        0.016       7.8  sshd.exe
03/19  12:04:46.180  11212   6428        0.016      13.3  conhost.exe
03/19  12:04:48.492  10572   6428        0.000       7.7  sshd.exe
03/19  12:04:48.503  11912  10572        0.047       5.4  conhost.exe

@DHowett
Copy link
Member

DHowett commented Mar 19, 2021

I can't figure out what you do not understand.

On the server, ConPTY reproduces the "screen" for the hosted console application. -AND-
ConPTY cannot reproduce wrapped lines. -THEREFORE-
ConPTY hard-wraps the screen for the hosted console application. -SO-
When you select text that came out of ConPTY, it is hard-wrapped.

@vefatica
Copy link
Author

I don't have a good idea what ConPTY is ... a capability of conhost.exe separate from that of supplying the usual console window? And while console windows do wrapping, ConPTY doesn't? I gather an up-to-date OpenConsole.exe is better at this?

@DHowett
Copy link
Member

DHowett commented Mar 19, 2021

You have been on, like, fourteen threads where I talk about ConPTY in an answer to your question yet you haven't ventured to ask what it is? Oi!

Yep! ConPTY is a way for conhost to convert Win32 console application output to VT sequences (and the same for input) such that normal terminal emulators can "host" windows console applications.

@zadjii-msft
Copy link
Member

You might also want to read: #57, https://docs.microsoft.com/en-us/windows/console/pseudoconsoles

@DHowett
Copy link
Member

DHowett commented Mar 19, 2021

As well as JDeBP's answer page about hosting console apps, which documents why it was so hard, for so long.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Needs-Tag-Fix Doesn't match tag requirements Needs-Triage It's a new issue that the core contributor team needs to triage at the next triage meeting
Projects
None yet
Development

No branches or pull requests

3 participants