Skip to content

Clear buffer: option to clear up to the current cursor line #18878

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

Open
elibarzilay opened this issue May 5, 2025 · 4 comments · May be fixed by #18976
Open

Clear buffer: option to clear up to the current cursor line #18878

elibarzilay opened this issue May 5, 2025 · 4 comments · May be fixed by #18976
Assignees
Labels
Area-TerminalControl Issues pertaining to the terminal control (input, selection, keybindings, mouse interaction, etc.) Needs-Tag-Fix Doesn't match tag requirements Product-Terminal The new Windows Terminal.

Comments

@elibarzilay
Copy link

Description of the new feature

This is a followup to #18732, which is locked. The request there is to have an option to preserve the current line in clearBuffer.

I don't have VS installed, so I can't play with the code, but I think that adding something like the below case to ControlCore::ClearBuffer should be very close to implementing this.

[It will fail in case of editing multi-line inputs, but as I described in the other issue, this is still hugely useful as a default over the current always-remove-everything option. The one thing that bothers me more about this is that it uses the beginning of the current physical line rather than the logical line. If there's a way to get that information, it would be much better.]

Proposed technical implementation details

Disclaimer: mostly made-up code based on what I see in the file. Also assumes that there's a .x and .y fields, and that they're 0-based.

        case ClearBufferType::AllToCursor:
            const til::point pos = _terminal->GetTextBuffer().GetCursor().GetPosition();
            if (til.y == 0)
            {
                // cursor at the top of the screen: just remove the scrollback
                command = L"\x1b[3J";
            }
            else
            {
                // otherwise: clear scrallback, move to top at the same column, delete rows up to cursor position
                command = fmt::format(FMT_COMPILE(L"\x1b[3J\x1b[H\x1b[{}M\x1b[1;{}H"), pos.y, pos.x + 1);
            }
            break;

For reference, a bash version of this:

clearToCursor() {
  # read cursor position
  IFS='[;' read -s -d R -p $'\e[6n' -r -u 0 _ ROW COL
  if [[ $ROW -eq 1 ]]; then
    # on top row => just clear the scrollback
    printf '\e[3J'
  else
    # clear scrollback, goto top, delete ROW-1 lines
    printf '\e[3J\e[H\e[%dM\e[1;%dH' $((ROW-1)) $COL
  fi
}
@elibarzilay elibarzilay added the Issue-Feature Complex enough to require an in depth planning process and actual budgeted, scheduled work. label May 5, 2025
@microsoft-github-policy-service microsoft-github-policy-service bot added 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 labels May 5, 2025
@elibarzilay
Copy link
Author

Two more bits of relevant information:

  • Now that FIX#18877 Triple-click to select logical line #18885 is merged, this could use the same logic to make it even better and preserve the last logical line rather than the physical one. (But I added a comment there that might be considered WRT a logical line that is partially visible.)

  • By complete chance, I was using CMD today, and tried clearing the buffer. The result is strange in a way that looks like things are complicated: it works as expected when nothing is type (ie, after an enter) -- but if I start typing stuff, then clear the buffer, then type more, the editing continues from the same place. Looks like once typing starts, whatever is CMD's idea of a line-editor does not get reset. I also tried powershell, and it's the same as CMD, except that even after an enter it behaves in the same broken way. Screen-recording follows:
20250510-0047-50.2968362.mp4

Sidenote: I only mention this for completeness, since whatever was the original issue that triggered the new behavior might have been related to how things work in CMD/PS, which I almost never use (and therefore how it's broken now is not something that I care much about :).

@elibarzilay
Copy link
Author

I was able to kind of install VS in a VM, not really in a productive way (since each recompilation took around 30m), but I did manage to verify that the following code seem to work:

            {
                const auto lock = _terminal->LockForWriting();
                const til::point pos = _terminal->GetCursorPosition();
                int ofs = ScrollOffset();
                if (pos.y - ofs == 0)
                {
                    // cursor is already at the top of the screen: just remove the scrollback
                    command = L"\x1b[3J";
                }
                else
                {
                    command = fmt::format(L"\x1b[3J\x1b[H\x1b[{}M\x1b[1;{}H", pos.y - ofs, pos.x + 1);
                }
            }

It's not ideal in releasing the lock just to re-grab it later when sending the string, but it does seem to do the trick.

Re my last comment, it would be nice to have that working too (clearing up to the beginning of the current logical line), but given the 30m recompilation cycle I gave up. For reference, there is a control sequence for scrolling up, eg: \x1b[2T to scroll two rows up.

@zadjii-msft zadjii-msft added Area-TerminalControl Issues pertaining to the terminal control (input, selection, keybindings, mouse interaction, etc.) Product-Terminal The new Windows Terminal. and removed Issue-Feature Complex enough to require an in depth planning process and actual budgeted, scheduled work. Needs-Triage It's a new issue that the core contributor team needs to triage at the next triage meeting labels May 14, 2025
@zadjii-msft zadjii-msft added this to the Terminal v1.25 milestone May 14, 2025
@lhecker
Copy link
Member

lhecker commented May 27, 2025

Your suggested fix doesn't take into account that the buffers between ConPTY and Windows Terminal should stay mostly synchronized. ClearBuffer clears the buffer fully which has useful properties. This puts the cursor at position 0,0. Since your approach only clears the Windows Terminal side, the cursors aren't synchronized anymore.

This is the entire crux why this behavior can't be changed trivially.
Edit: While on a walk I think I had an idea how to fix this "simply" and somewhat elegantly.
Edit 2: Doesn't work. Fuck it. Shitty solution it is.

@elibarzilay
Copy link
Author

  1. My suggestion uses only control sequences -- are they not implemented properly somehow?

  2. See the second part in my earlier comment: it is currently already broken in CMD/PS, which makes me think that the answer to the above is "yes".

  3. Regardless, it seems to me like a good direction to implement a control-sequence-only solution independently of fixing whatever's broken. More so given that it's broken in CMD/PS anyway.

@lhecker lhecker linked a pull request May 28, 2025 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-TerminalControl Issues pertaining to the terminal control (input, selection, keybindings, mouse interaction, etc.) Needs-Tag-Fix Doesn't match tag requirements Product-Terminal The new Windows Terminal.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants