less with -r option causes strange display behavior for input with ANSI control characters #12600

Open
opened 2026-01-31 03:20:01 +00:00 by claunia · 8 comments
Owner

Originally created by @zachmu on GitHub (Feb 15, 2021).

Originally assigned to: @DHowett on GitHub.

Environment

Windows build number: [run `[Environment]::OSVersion` for powershell, or `ver` for cmd]: 10.0.19041.0
Windows Terminal version (if applicable): 1.5.10411.0

Any other software?
Ubuntu on WSL 1

Steps to reproduce

Have a long file, in this case produced with git reflog. Examine with less. Notice that output does not include the first ~10 lines.

git reflog > reflog.out
head reflog.out
5240aea1 HEAD@{0}: checkout: moving from zachmu/windows to aaron/indexed-in-subquery-filter
56ac2928 HEAD@{1}: checkout: moving from aaron/indexed-in-subquery-filter to zachmu/windows
5240aea1 HEAD@{2}: checkout: moving from zachmu/windows to aaron/indexed-in-subquery-filter
56ac2928 HEAD@{3}: checkout: moving from aaron/indexed-in-subquery-filter to zachmu/windows
5240aea1 HEAD@{4}: checkout: moving from master to aaron/indexed-in-subquery-filter
1acb0aab HEAD@{5}: pull: Fast-forward
66627818 HEAD@{6}: checkout: moving from zachmu/windows to master
56ac2928 HEAD@{7}: commit: Added some more query tests for window funcs
cb14e839 HEAD@{8}: commit: Working row_number() function
5f08c885 HEAD@{9}: commit: Semi working sort order. Moved more functions and types around to avoid cycles.

less reflog presents me with a screen that starts like this:

rtField up to the sql package and gave it some more methods.
e9c3d6d8 HEAD@{11}: commit: Added window setting to function analysis
98044728 HEAD@{12}: commit: Chalked in outline of adding all rows to a window expression. Now need a way to get Window values into the functions.
d8fcf55e HEAD@{13}: commit: Sketched out an iter
000efaba HEAD@{14}: commit: Chalked out a window node. This involved moving some Sort related types out of the plan package to the expression package
66627818 HEAD@{15}: checkout: moving from master to zachmu/windows

As you can see, the first ~10 lines of the file are not there. If I press the up arrow, less does not respond (chimes the bell). If I press the down arrow key twice, then the up arrow key twice, I see this:

5240aea1 HEAD@{0}: checkout: moving from zachmu/windows to aaron/indexed-in-subquery-filter
56ac2928 HEAD@{1}: checkout: moving from aaron/indexed-in-subquery-filter to zachmu/windows
98044728 HEAD@{12}: commit: Chalked in outline of adding all rows to a window expression. Now need a way to get Window values into the functions.
d8fcf55e HEAD@{13}: commit: Sketched out an iter

Something very strange is happening with the display buffering here. I've noticed this on other invocations of less as well, not just when examining this particular file.

Expected behavior

When less is invoked the terminal should contain the first page of text from the input. Instead, it's starting about 10 lines in.

Actual behavior

As described above

Originally created by @zachmu on GitHub (Feb 15, 2021). Originally assigned to: @DHowett on GitHub. # Environment ``` Windows build number: [run `[Environment]::OSVersion` for powershell, or `ver` for cmd]: 10.0.19041.0 Windows Terminal version (if applicable): 1.5.10411.0 Any other software? Ubuntu on WSL 1 ``` # Steps to reproduce Have a long file, in this case produced with `git reflog.` Examine with `less`. Notice that output does not include the first ~10 lines. ``` git reflog > reflog.out head reflog.out 5240aea1 HEAD@{0}: checkout: moving from zachmu/windows to aaron/indexed-in-subquery-filter 56ac2928 HEAD@{1}: checkout: moving from aaron/indexed-in-subquery-filter to zachmu/windows 5240aea1 HEAD@{2}: checkout: moving from zachmu/windows to aaron/indexed-in-subquery-filter 56ac2928 HEAD@{3}: checkout: moving from aaron/indexed-in-subquery-filter to zachmu/windows 5240aea1 HEAD@{4}: checkout: moving from master to aaron/indexed-in-subquery-filter 1acb0aab HEAD@{5}: pull: Fast-forward 66627818 HEAD@{6}: checkout: moving from zachmu/windows to master 56ac2928 HEAD@{7}: commit: Added some more query tests for window funcs cb14e839 HEAD@{8}: commit: Working row_number() function 5f08c885 HEAD@{9}: commit: Semi working sort order. Moved more functions and types around to avoid cycles. ``` `less reflog` presents me with a screen that starts like this: ``` rtField up to the sql package and gave it some more methods. e9c3d6d8 HEAD@{11}: commit: Added window setting to function analysis 98044728 HEAD@{12}: commit: Chalked in outline of adding all rows to a window expression. Now need a way to get Window values into the functions. d8fcf55e HEAD@{13}: commit: Sketched out an iter 000efaba HEAD@{14}: commit: Chalked out a window node. This involved moving some Sort related types out of the plan package to the expression package 66627818 HEAD@{15}: checkout: moving from master to zachmu/windows ``` As you can see, the first ~10 lines of the file are not there. If I press the up arrow, less does not respond (chimes the bell). If I press the down arrow key twice, then the up arrow key twice, I see this: ``` 5240aea1 HEAD@{0}: checkout: moving from zachmu/windows to aaron/indexed-in-subquery-filter 56ac2928 HEAD@{1}: checkout: moving from aaron/indexed-in-subquery-filter to zachmu/windows 98044728 HEAD@{12}: commit: Chalked in outline of adding all rows to a window expression. Now need a way to get Window values into the functions. d8fcf55e HEAD@{13}: commit: Sketched out an iter ``` Something very strange is happening with the display buffering here. I've noticed this on other invocations of `less` as well, not just when examining this particular file. # Expected behavior When `less` is invoked the terminal should contain the first page of text from the input. Instead, it's starting about 10 lines in. # Actual behavior As described above
claunia added the Area-OutputIssue-BugNeeds-AttentionProduct-TerminalPriority-2 labels 2026-01-31 03:20:01 +00:00
Author
Owner

@DHowett commented on GitHub (Feb 15, 2021):

Do you have anything in your startup scripts that would change the size of the console window (MODE CON LINES=, $Host.UI.RawUI.WindowSize=, stty, printf "\e[..........t", etc.?)

@DHowett commented on GitHub (Feb 15, 2021): Do you have anything in your startup scripts that would change the size of the console window (`MODE CON LINES=`, `$Host.UI.RawUI.WindowSize=`, `stty`, `printf "\e[..........t"`, etc.?)
Author
Owner

@zachmu commented on GitHub (Feb 15, 2021):

Good question!

Digging through my .zshrc, it appears this line is the culprit:

export LESS=-r

Unsetting this var fixes the issue. Presumably triggered by ANSI color codes in the output of various git commands where I've noticed this?

I don't know if this is a windows terminal problem or not. I do know I've had that line in my .zshrc for over a decade and never noticed a problem before using windows terminal.

@zachmu commented on GitHub (Feb 15, 2021): Good question! Digging through my .zshrc, it appears this line is the culprit: `export LESS=-r` Unsetting this var fixes the issue. Presumably triggered by ANSI color codes in the output of various git commands where I've noticed this? I don't know if this is a windows terminal problem or not. I do know I've had that line in my .zshrc for over a decade and never noticed a problem before using windows terminal.
Author
Owner

@DHowett commented on GitHub (Feb 15, 2021):

Really curious, that. When you remove -r, do you see any control sequences in the less output?

@DHowett commented on GitHub (Feb 15, 2021): Really curious, that. When you remove `-r`, do you _see_ any control sequences in the `less` output?
Author
Owner

@zachmu commented on GitHub (Feb 15, 2021):

Nope, I don't see any printed control sequences in the output.

I notice that the man page for less has this to say about the -r option:

  •   -r or --raw-control-chars
             Causes  "raw" control characters to be displayed.  The default is to display control characters using the caret
    
  •          notation; for example, a control-A (octal 001) is displayed as "^A".  Warning: when the -r option is used, less
             cannot keep track of the actual appearance of the screen (since this depends on how the screen responds to each
             type of control character).  Thus, various display problems may result, such as long lines being split  in  the
             wrong place.
    

So maybe this is the whole of the story? Still not sure if this is a problem with WSL / windows terminal or not.

For anyone reading, this is the current value of $LESS, which gets rid of the problem for me:

% echo $LESS
-F -i -J -M -R -W -x4 -X -z-4
@zachmu commented on GitHub (Feb 15, 2021): Nope, I don't see any printed control sequences in the output. I notice that the man page for less has this to say about the -r option: * -r or --raw-control-chars Causes "raw" control characters to be displayed. The default is to display control characters using the caret * notation; for example, a control-A (octal 001) is displayed as "^A". Warning: when the -r option is used, less cannot keep track of the actual appearance of the screen (since this depends on how the screen responds to each type of control character). Thus, various display problems may result, such as long lines being split in the wrong place. So maybe this is the whole of the story? Still not sure if this is a problem with WSL / windows terminal or not. For anyone reading, this is the current value of $LESS, which gets rid of the problem for me: ``` % echo $LESS -F -i -J -M -R -W -x4 -X -z-4 ```
Author
Owner

@DHowett commented on GitHub (Feb 17, 2021):

Alright, one more thing to troubleshoot.

Can you get it in a state where it'll reproduce, and then hit me with a script? It should be in the bsdutils package.

$ script
< script will spawn a subshell here >
$ # do the repro
$ exit
< script will tell you what file it wrote the output to, usually called "typescript" >

If you're not comfortable sharing typescript publicly, you can send it to my GitHub profile's e-mail address.
If you're not comfortable sharing typescript privately, you get to pick through it to find what control sequence less is emitting that we're catching and handling.

@DHowett commented on GitHub (Feb 17, 2021): Alright, one more thing to troubleshoot. Can you get it in a state where it'll reproduce, and then hit me with a `script`? It should be in the `bsdutils` package. ``` $ script < script will spawn a subshell here > $ # do the repro $ exit < script will tell you what file it wrote the output to, usually called "typescript" > ``` If you're not comfortable sharing `typescript` publicly, you can send it to my GitHub profile's e-mail address. If you're not comfortable sharing `typescript` _privately_, you get to pick through it to find what control sequence less is emitting that we're catching and handling.
Author
Owner

@DHowett commented on GitHub (Feb 17, 2021):

(It'll capture all the unparsed VT coming out of any of its child processes.)

@DHowett commented on GitHub (Feb 17, 2021): (It'll capture all the unparsed VT coming out of any of its child processes.)
Author
Owner

@ghost commented on GitHub (Feb 21, 2021):

This issue has been automatically marked as stale because it has been marked as requiring author feedback but has not had any activity for 4 days. It will be closed if no further activity occurs within 3 days of this comment.

@ghost commented on GitHub (Feb 21, 2021): This issue has been automatically marked as stale because it has been marked as requiring author feedback but has not had any activity for **4 days**. It will be closed if no further activity occurs **within 3 days of this comment**.
Author
Owner

@zachmu commented on GitHub (Feb 22, 2021):

Here you go! (zipped because github only accepts certain file types)

Repro was:

less reflog.out

With LESS=-r

typescript.zip

@zachmu commented on GitHub (Feb 22, 2021): Here you go! (zipped because github only accepts certain file types) Repro was: `less reflog.out` With `LESS=-r` [typescript.zip](https://github.com/microsoft/terminal/files/6025739/typescript.zip)
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#12600