Extra newline when copying line with wide glyph on the edge #15849

Open
opened 2026-01-31 04:50:17 +00:00 by claunia · 6 comments
Owner

Originally created by @Kagami on GitHub (Nov 11, 2021).

Windows Terminal version (or Windows build number)

10.0.19043.1348, 1.12.2931.0

Other Software

Ubuntu 21.04 in WSL

Steps to reproduce

  1. Open tab with some WSL distro, shouldn't matter which.

  2. Create python3 file with the following content:

import os
import sys
cols = os.get_terminal_size().columns
sys.stdout.buffer.write(b'a'*(cols-1))
sys.stdout.buffer.write(b'\xea\xb0\x9c')
  1. Run it:
python3 1.py
  1. Copy output with the mouse and paste to some editor.

Expected Behavior

There should be only single line of text.

Actual Behavior

There're two lines of text, see screenshots.

1
2

The problem doesn't appear if that 3-byte symbol is not on the edge of the line. Also 2-byte symbols work fine too.

Originally created by @Kagami on GitHub (Nov 11, 2021). ### Windows Terminal version (or Windows build number) 10.0.19043.1348, 1.12.2931.0 ### Other Software Ubuntu 21.04 in WSL ### Steps to reproduce 1. Open tab with some WSL distro, shouldn't matter which. 2. Create python3 file with the following content: ```python import os import sys cols = os.get_terminal_size().columns sys.stdout.buffer.write(b'a'*(cols-1)) sys.stdout.buffer.write(b'\xea\xb0\x9c') ``` 3. Run it: ```bash python3 1.py ``` 4. Copy output with the mouse and paste to some editor. ### Expected Behavior There should be only single line of text. ### Actual Behavior There're two lines of text, see screenshots. ![1](https://user-images.githubusercontent.com/533383/141378349-7ccab42d-d1e2-47c4-976e-f2be0ea33abc.png) ![2](https://user-images.githubusercontent.com/533383/141378343-bf8d1612-6b0a-4c4b-85dc-08a5ba018094.png) The problem doesn't appear if that 3-byte symbol is not on the edge of the line. Also 2-byte symbols work fine too.
claunia added the Area-OutputIssue-BugProduct-ConptyPriority-2 labels 2026-01-31 04:50:17 +00:00
Author
Owner

@zadjii-msft commented on GitHub (Nov 16, 2021):

Hmm. Doesn't repro in conhost. So this is probably a conpty wrapping bug. Probably related to #5800 in some way I don't fully know yet. Thanks for the minimal repro!

@zadjii-msft commented on GitHub (Nov 16, 2021): Hmm. Doesn't repro in conhost. So this is probably a conpty wrapping bug. Probably related to #5800 in some way I don't fully know yet. Thanks for the minimal repro!
Author
Owner

@Kagami commented on GitHub (Dec 3, 2021):

GNOME Terminal in native Linux also wraps the line -- as it should, I think.

The problem is not the line wrapping, it's the extra newline when I copy the output to the clipboard.

This problem doesn't happen with two-byte symbols (single column), e.g.:

sys.stdout.buffer.write(b'a'*(cols-1))
sys.stdout.buffer.write('тест'.encode('utf-8'))

a

@Kagami commented on GitHub (Dec 3, 2021): >GNOME Terminal in native Linux also wraps the line -- as it should, I think. The problem is not the line wrapping, it's the extra newline when I copy the output to the clipboard. This problem doesn't happen with two-byte symbols (single column), e.g.: ```python sys.stdout.buffer.write(b'a'*(cols-1)) sys.stdout.buffer.write('тест'.encode('utf-8')) ``` ![a](https://user-images.githubusercontent.com/533383/144597654-d7757768-e7d0-47f1-bb7f-e6d288cb3c88.png)
Author
Owner

@Kagami commented on GitHub (Dec 3, 2021):

Works fine in this case too:

sys.stdout.buffer.write(b'a'*(cols-2))
sys.stdout.buffer.write(b'\xea\xb0\x9c')
sys.stdout.buffer.write(b'\xea\xb0\x9c')

It seems be related to the fact that there's only 1 column left on the current line but the character takes 2 columns.

image

@Kagami commented on GitHub (Dec 3, 2021): Works fine in this case too: ```python sys.stdout.buffer.write(b'a'*(cols-2)) sys.stdout.buffer.write(b'\xea\xb0\x9c') sys.stdout.buffer.write(b'\xea\xb0\x9c') ``` It seems be related to the fact that there's only 1 column left on the current line but the character takes 2 columns. ![image](https://user-images.githubusercontent.com/533383/144599036-8fd9990a-a3f3-412f-acd7-291ae91a49a7.png)
Author
Owner

@eryksun commented on GitHub (Dec 3, 2021):

The problem is not the line wrapping, it's the extra newline when I copy the output to the clipboard.

Sorry, I misunderstood that the problem was the newline itself in the output. I see now that it shouldn't be there and normally isn't, except when a wide glyph is wrapped at the edge.

To me, the following example more clearly emphasizes that the character is known to be a wide glyph that prints in two columns (hence dividing the column count by 2), and that it's expected to wrap in the terminal by one character. The bug is just that the terminal adds a line-feed (LF) character where it wraps the line for display.

>>> os.get_terminal_size().columns
133
>>> print('\uac1c' * (os.get_terminal_size().columns // 2 + 1))
개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개
개

>>> os.get_terminal_size().columns
132
>>> print('\uac1c' * (os.get_terminal_size().columns // 2 + 1))
개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개

The output copied from the terminal with an odd number of columns (133) should not have the LF before the last "개" character. This example works fine with an even number of columns, for which a wide glyph doesn't straddle the edge.

Now that I know what I'm looking for, I see that conhost in Windows 10 and 11 is also wrong, but in a different way. For example:

>>> os.get_terminal_size().columns
133
>>> print('\uac1c' * (os.get_terminal_size().columns // 2 + 1))
개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개 개

>>> os.get_terminal_size().columns
132
>>> print('\uac1c' * (os.get_terminal_size().columns // 2 + 1))
개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개

That's an ASCII space (0x20) inserted where the line was wrapped for display. It's not present when the line wrap occurs on a single-column character, or for this example when there is an even number of columns.

@eryksun commented on GitHub (Dec 3, 2021): > The problem is not the line wrapping, it's the extra newline when I copy the output to the clipboard. Sorry, I misunderstood that the problem was the newline itself in the output. I see now that it shouldn't be there and normally isn't, except when a wide glyph is wrapped at the edge. To me, the following example more clearly emphasizes that the character is known to be a wide glyph that prints in two columns (hence dividing the column count by 2), and that it's expected to wrap in the terminal by one character. The bug is just that the terminal adds a line-feed (LF) character where it wraps the line for display. ```python >>> os.get_terminal_size().columns 133 >>> print('\uac1c' * (os.get_terminal_size().columns // 2 + 1)) 개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개 개 >>> os.get_terminal_size().columns 132 >>> print('\uac1c' * (os.get_terminal_size().columns // 2 + 1)) 개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개 ``` The output copied from the terminal with an odd number of columns (133) should not have the LF before the last "개" character. This example works fine with an even number of columns, for which a wide glyph doesn't straddle the edge. Now that I know what I'm looking for, I see that conhost in Windows 10 and 11 is also wrong, but in a different way. For example: ```python >>> os.get_terminal_size().columns 133 >>> print('\uac1c' * (os.get_terminal_size().columns // 2 + 1)) 개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개 개 >>> os.get_terminal_size().columns 132 >>> print('\uac1c' * (os.get_terminal_size().columns // 2 + 1)) 개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개개 ``` That's an ASCII space (0x20) inserted where the line was wrapped for display. It's not present when the line wrap occurs on a single-column character, or for this example when there is an even number of columns.
Author
Owner

@Kagami commented on GitHub (Dec 3, 2021):

Thanks for clarification, I modified issue's title accordingly.

@Kagami commented on GitHub (Dec 3, 2021): Thanks for clarification, I modified issue's title accordingly.
Author
Owner

@eryksun commented on GitHub (Dec 3, 2021):

I updated my last comment to use the same screen sizes in Windows Terminal and conhost, and also to show that the bug only occurs for me when the number of columns in the terminal is odd, which causes a wide glyph to straddle the edge.

@eryksun commented on GitHub (Dec 3, 2021): I updated my last comment to use the same screen sizes in Windows Terminal and conhost, and also to show that the bug only occurs for me when the number of columns in the terminal is odd, which causes a wide glyph to straddle the edge.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#15849