Virtual Terminal Sequences for Simple Cursor Positioning don't work #14927

Closed
opened 2026-01-31 04:23:24 +00:00 by claunia · 11 comments
Owner

Originally created by @Toxaris on GitHub (Aug 22, 2021).

Originally assigned to: @DHowett on GitHub.

Windows Terminal version (or Windows build number)

10.0.19042.1165

Other Software

No response

Steps to reproduce

Activate virtual terminal processing and print "Hello, world!\x1bD?" to stdout.

Expected Behavior

Based on the documentation about virtual terminal sequences for simple cursor positioning I expect to see:

Hello, World?

That is, I expect that \x1bD moves the cursor left over the ! and then the ? is printed over the !.

In other words, I expect that \x1bD works like \x1b[1D.

Actual Behavior

I see:

Hello, World!
             ?
Originally created by @Toxaris on GitHub (Aug 22, 2021). Originally assigned to: @DHowett on GitHub. ### Windows Terminal version (or Windows build number) 10.0.19042.1165 ### Other Software _No response_ ### Steps to reproduce Activate virtual terminal processing and print `"Hello, world!\x1bD?"` to stdout. ### Expected Behavior Based on the documentation about [virtual terminal sequences for simple cursor positioning](https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences#simple-cursor-positioning) I expect to see: ``` Hello, World? ``` That is, I expect that `\x1bD` moves the cursor left over the `!` and then the `?` is printed over the `!`. In other words, I expect that `\x1bD` works like `\x1b[1D`. ### Actual Behavior I see: ``` Hello, World! ? ```
claunia added the Needs-TriageNeeds-Tag-FixIssue-Docs labels 2026-01-31 04:23:25 +00:00
Author
Owner

@orcmid commented on GitHub (Aug 22, 2021):

You need to contend with the fact that in C# the D is viewed as a hex digit and it is taken as part of the \x1bD. I suggest you try a simple \x08 to get the backspace you want in this particular case. Or use the official VT escape sequence.

@orcmid commented on GitHub (Aug 22, 2021): You need to contend with the fact that in C# the D is viewed as a hex digit and it is taken as part of the \x1bD. I suggest you try a simple \x08 to get the backspace you want in this particular case. Or use the official VT escape sequence.
Author
Owner

@vefatica commented on GitHub (Aug 22, 2021):

Or tell it where the escape sequence ends: Printf(L"Hello, world!\x1b\D?");

@vefatica commented on GitHub (Aug 22, 2021): Or tell it where the escape sequence ends: `Printf(L"Hello, world!\x1b\D?");`
Author
Owner

@vefatica commented on GitHub (Aug 22, 2021):

Or use a less troublesome version.

Printf(L"Hello, world!\x1b[D?");
Printf(L"Hello, world!\x1b[1D?");
@vefatica commented on GitHub (Aug 22, 2021): Or use a less troublesome version. ``` Printf(L"Hello, world!\x1b[D?"); Printf(L"Hello, world!\x1b[1D?"); ```
Author
Owner

@Toxaris commented on GitHub (Aug 22, 2021):

Interesting point about the \x consuming the D. However, I'm using Rust, and I'm pretty sure that \x in Rust always consumes exactly the next two hexadecimal digits. See Rust reference on character escapes.

To double check, I tried the following program:

println!("Hello, world!\x1b[D?");

println!("Hello, world!\x1bD?");

print!("Hello, world!\x1b");
print!("D");
println!("?");

I see the following output in the integrated terminal in VS Code:

Hello, world?
             Hello, world?
                          Hello, world?

And the following output in Windows terminal:

Hello, world?
             Hello, world!
                          ?
                           Hello, world!
                                        ?

(The text keeps going to the right because I also set DISABLE_NEWLINE_AUTO_RETURN)

So in the integrated terminal in VS Code, \x1bD behaves like \x1b[D, but in Windows terminal, they behave differently.

@Toxaris commented on GitHub (Aug 22, 2021): Interesting point about the `\x` consuming the `D`. However, I'm using Rust, and I'm pretty sure that `\x` in Rust always consumes exactly the next two hexadecimal digits. See [Rust reference on character escapes](https://doc.rust-lang.org/stable/reference/tokens.html#character-escapes). To double check, I tried the following program: ```rust println!("Hello, world!\x1b[D?"); println!("Hello, world!\x1bD?"); print!("Hello, world!\x1b"); print!("D"); println!("?"); ``` I see the following output in the integrated terminal in VS Code: ``` Hello, world? Hello, world? Hello, world? ``` And the following output in Windows terminal: ``` Hello, world? Hello, world! ? Hello, world! ? ``` (The text keeps going to the right because I also set `DISABLE_NEWLINE_AUTO_RETURN`) So in the integrated terminal in VS Code, `\x1bD` behaves like `\x1b[D`, but in Windows terminal, they behave differently.
Author
Owner

@Toxaris commented on GitHub (Aug 22, 2021):

I hunted around in the source code a bit and I found the following leads in terminal/parser/OutputStateMachineEngine:

It appears that the simple cursor positioning codes from the article on docs.microsoft.com are simply not implemented in Windows terminal? Maybe because Windows terminal chooses to emulate a different terminal than described in that article?

@Toxaris commented on GitHub (Aug 22, 2021): I hunted around in the source code a bit and I found the following leads in `terminal/parser/OutputStateMachineEngine`: - `EscActionCodes::IND_Index` is `D`: https://github.com/microsoft/terminal/blob/0c901edd813f2bb61a52c3aca5384eb4d748b868/src/terminal/parser/OutputStateMachineEngine.hpp#L77 - `EscActionCodes::IND_Index` is dispatched as line feed without return (as expected from the name): https://github.com/microsoft/terminal/blob/0c901edd813f2bb61a52c3aca5384eb4d748b868/src/terminal/parser/OutputStateMachineEngine.cpp#L220-L223 It appears that the simple cursor positioning codes from the [article on docs.microsoft.com](https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences#simple-cursor-positioning) are simply not implemented in Windows terminal? Maybe because Windows terminal chooses to emulate a different terminal than described in that article?
Author
Owner

@Toxaris commented on GitHub (Aug 22, 2021):

I suggest you try a simple \x08 to get the backspace you want in this particular case. Or use the official VT escape sequence.

Thanks. I'm not blocked on this, since \x1b[1D works fine, and I think I need absolute positioning anyway.

How I run into this:

When researching the Windows Console API docs.microsoft.com, I came across the recommendation to discontinue use of the classic console API which links to the documentation about virtual terminal sequences as a more modern and platform-independent replacement. And that documentation first introduces the ESC A, ESC B, ESC C, and ESC D sequences for simple cursor movement, so I decided to use them for trying out whether I got my basic setup right. ESC D seemed easiest to produce a visual effect with a simple println!.

It is unfortunate that the documentation leads developers into experimenting with virtual terminal sequences which are not support by Windows terminal. Since they are documented there, I assume they are "official VT escape sequences", though.

@Toxaris commented on GitHub (Aug 22, 2021): > I suggest you try a simple \x08 to get the backspace you want in this particular case. Or use the official VT escape sequence. Thanks. I'm not blocked on this, since `\x1b[1D` works fine, and I think I need absolute positioning anyway. How I run into this: When researching the Windows Console API docs.microsoft.com, I came across the [recommendation to discontinue use of the classic console API](https://docs.microsoft.com/en-us/windows/console/classic-vs-vt) which links to the [documentation about virtual terminal sequences](https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences) as a more modern and platform-independent replacement. And that documentation first introduces the `ESC A`, `ESC B`, `ESC C`, and `ESC D` sequences for simple cursor movement, so I decided to use them for trying out whether I got my basic setup right. `ESC D` seemed easiest to produce a visual effect with a simple `println!`. It is unfortunate that the documentation leads developers into experimenting with virtual terminal sequences which are not support by Windows terminal. Since they are documented there, I assume they are "official VT escape sequences", though.
Author
Owner

@j4james commented on GitHub (Aug 22, 2021):

Sorry for the confusion, but that's a mistake in the documentation. The first four "Simple Cursor Positioning" commands are actually VT52 sequences that only active in VT52 mode. In the default "ANSI" mode, they mean something completely different, although the only one that's currently implemented is ESC D (this is the "Index" command, which moves the cursor down).

@j4james commented on GitHub (Aug 22, 2021): Sorry for the confusion, but that's a mistake in the documentation. The first four "Simple Cursor Positioning" commands are actually VT52 sequences that only active in VT52 mode. In the default "ANSI" mode, they mean something completely different, although the only one that's currently implemented is `ESC D` (this is the "Index" command, which moves the cursor down).
Author
Owner

@Toxaris commented on GitHub (Aug 22, 2021):

Thanks @j4james, that makes sense. So the proper fix is to update the documentation. To my delight, I see that it is also on github, so I opened a PR. Interesting to see what will come of it.

@Toxaris commented on GitHub (Aug 22, 2021): Thanks @j4james, that makes sense. So the proper fix is to update the documentation. To my delight, I see that it is also on github, so I opened a PR. Interesting to see what will come of it.
Author
Owner

@Toxaris commented on GitHub (Aug 22, 2021):

Hmm wait this doesn't explain why the terminal integrated into VS Code interpretes the codes differently than Windows Terminal. Do they use different default configurations? Why?

@Toxaris commented on GitHub (Aug 22, 2021): Hmm wait this doesn't explain why the terminal integrated into VS Code interpretes the codes differently than Windows Terminal. Do they use different default configurations? Why?
Author
Owner

@j4james commented on GitHub (Aug 22, 2021):

Do they use different default configurations? Why?

The behavior described in the documentation is the way the code used to work. That was corrected a while back, but those corrections take a while to make their way into the conhost that is included with Windows itself. Windows Terminal bundles its own build of conhost, so it always has the latest fixes. I'm guessing VS Code just uses the conhost included with Windows, or at least is not using the most recent version.

@j4james commented on GitHub (Aug 22, 2021): > Do they use different default configurations? Why? The behavior described in the documentation is the way the code used to work. That was corrected a while back, but those corrections take a while to make their way into the conhost that is included with Windows itself. Windows Terminal bundles its own build of conhost, so it always has the latest fixes. I'm guessing VS Code just uses the conhost included with Windows, or at least is not using the most recent version.
Author
Owner

@DHowett commented on GitHub (Aug 23, 2021):

Yep- VS Code uses the version of conhost that ships with Windows. James, I found that you noted this change in the Compatibility section of your spec document when you originally gave us VT52 support. I'm eternally grateful that we've written so much stuff down.

@Toxaris sorry about the documentation miss, and thank you for bringing it to our attention 😄

I'll close this one out when we merge the updated docs!

@DHowett commented on GitHub (Aug 23, 2021): Yep- VS Code uses the version of conhost that ships with Windows. James, I found that you noted this change in [the Compatibility section](https://github.com/microsoft/terminal/blob/main/doc/specs/%23976%20-%20VT52%20escape%20sequences.md#compatibility) of your spec document when you originally gave us VT52 support. I'm eternally grateful that we've written so much stuff down. @Toxaris sorry about the documentation miss, and thank you for bringing it to our attention 😄 I'll close this one out when we merge the updated docs!
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#14927