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

Closed
opened 2026-01-31 03:32:49 +00:00 by claunia · 21 comments
Owner

Originally created by @vefatica on GitHub (Mar 18, 2021).

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

Thanks!

Originally created by @vefatica on GitHub (Mar 18, 2021). How is the wrap/nowrap behavior when copying multiple lines handled? Is it controlable with SetConsoleMode? Thanks!
claunia added the Needs-TriageNeeds-Tag-Fix labels 2026-01-31 03:32:49 +00:00
Author
Owner

@DHowett commented on GitHub (Mar 18, 2021):

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

@DHowett commented on GitHub (Mar 18, 2021): Applications what write off the end of the line force a wrap. You can disable "deferred EOL" with SetConsoleMode.
Author
Owner

@vefatica commented on GitHub (Mar 18, 2021):

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 commented on GitHub (Mar 18, 2021): 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?
Author
Owner

@vefatica commented on GitHub (Mar 18, 2021):

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?

@vefatica commented on GitHub (Mar 18, 2021): 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](https://user-images.githubusercontent.com/61856645/111669526-459f5180-87ed-11eb-90a0-3b898dc1c281.png) When I copy (right-click) and paste into an editor, I get ![image](https://user-images.githubusercontent.com/61856645/111669145-dde90680-87ec-11eb-8b08-4ad8adb04446.png) What can lead to this ... the command not wrapped and the output wrapped after copy/paste?
Author
Owner

@DHowett commented on GitHub (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.

@DHowett commented on GitHub (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.
Author
Owner

@vefatica commented on GitHub (Mar 18, 2021):

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

@vefatica commented on GitHub (Mar 18, 2021): Sorry about that! I'm noted for impatience. I can't be the only person who has grown accustomed to your attentiveness.
Author
Owner

@DHowett commented on GitHub (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 commented on GitHub (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
Author
Owner

@DHowett commented on GitHub (Mar 18, 2021):

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

@DHowett commented on GitHub (Mar 18, 2021): (Sorry -- edited the above to fix an out of order bullet that somewhat changes the meaning.)
Author
Owner

@vefatica commented on GitHub (Mar 18, 2021):

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?

@vefatica commented on GitHub (Mar 18, 2021): 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?
Author
Owner

@DHowett commented on GitHub (Mar 18, 2021):

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

Sorry! 😄

@DHowett commented on GitHub (Mar 18, 2021): Nope, both of those will wrap. There is no console mode that will disable wrapping. Sorry! :smile:
Author
Owner

@DHowett commented on GitHub (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.

@DHowett commented on GitHub (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.
Author
Owner

@zadjii-msft commented on GitHub (Mar 18, 2021):

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 ☺️

@zadjii-msft commented on GitHub (Mar 18, 2021): 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 ☺️
Author
Owner

@vefatica commented on GitHub (Mar 18, 2021):

(#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.]

@vefatica commented on GitHub (Mar 18, 2021): (#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.]
Author
Owner

@DHowett commented on GitHub (Mar 18, 2021):

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

@DHowett commented on GitHub (Mar 18, 2021): SSH uses an old version of ConPTY :smile: which did not support line wrapping!
Author
Owner

@vefatica commented on GitHub (Mar 19, 2021):

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.

@vefatica commented on GitHub (Mar 19, 2021): > 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.
Author
Owner

@DHowett commented on GitHub (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.

@DHowett commented on GitHub (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_.
Author
Owner

@vefatica commented on GitHub (Mar 19, 2021):

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
@vefatica commented on GitHub (Mar 19, 2021): 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 ```
Author
Owner

@DHowett commented on GitHub (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.

@DHowett commented on GitHub (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.
Author
Owner

@vefatica commented on GitHub (Mar 19, 2021):

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?

@vefatica commented on GitHub (Mar 19, 2021): 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?
Author
Owner

@DHowett commented on GitHub (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.

@DHowett commented on GitHub (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.
Author
Owner

@zadjii-msft commented on GitHub (Mar 19, 2021):

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

@zadjii-msft commented on GitHub (Mar 19, 2021): You might also want to read: #57, https://docs.microsoft.com/en-us/windows/console/pseudoconsoles
Author
Owner

@DHowett commented on GitHub (Mar 19, 2021):

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

@DHowett commented on GitHub (Mar 19, 2021): As well as [JDeBP's answer page about hosting console apps](http://jdebp.info./FGA/capture-console-win32.html), which documents why it was _so hard, for so long_.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#13070