Skip to content
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

Add support for paste filtering and bracketed paste mode #9034

Merged

Conversation

skyline75489
Copy link
Collaborator

@skyline75489 skyline75489 commented Feb 4, 2021

This adds "paste filtering" & "bracketed paste mode" to the Windows
Terminal.

I've moved the paste handling code in TerminalControl to
Microsoft::Console::Util to be able to easily test it, and the paste
transformer from TerminalControl to TerminalCore.

Supersedes #7508
References #395 (overall bracketed paste support request)

Tests added. Manually tested.

@ghost ghost added Area-VT Virtual Terminal sequence support Issue-Feature Complex enough to require an in depth planning process and actual budgeted, scheduled work. Product-Conhost For issues in the Console codebase labels Feb 4, 2021
@github-actions

This comment has been minimized.

src/types/utils.cpp Outdated Show resolved Hide resolved
@github-actions

This comment has been minimized.

@skyline75489 skyline75489 changed the title Add support for paste filtering and bracketed paste mode" Add support for paste filtering and bracketed paste mode Feb 4, 2021
@github-actions

This comment has been minimized.

src/types/inc/utils.hpp Outdated Show resolved Hide resolved
src/types/utils.cpp Outdated Show resolved Hide resolved
@skyline75489
Copy link
Collaborator Author

Misspellings found, please review:

  • ALot

This is why we need better AI 😅

src/types/inc/utils.hpp Outdated Show resolved Hide resolved
@zadjii-msft zadjii-msft self-assigned this Feb 4, 2021
src/types/inc/utils.hpp Outdated Show resolved Hide resolved
src/types/inc/utils.hpp Outdated Show resolved Hide resolved
src/cascadia/TerminalControl/TermControl.cpp Outdated Show resolved Hide resolved
src/types/utils.cpp Show resolved Hide resolved
src/types/inc/utils.hpp Outdated Show resolved Hide resolved
@ghost ghost added the Needs-Author-Feedback The original author of the issue/PR needs to come back and respond to something label Feb 5, 2021
@DHowett
Copy link
Member

DHowett commented Feb 5, 2021

I love this. Thank you 😀

@ghost ghost removed the Needs-Author-Feedback The original author of the issue/PR needs to come back and respond to something label Feb 5, 2021

_terminal->ClearSelection();
_terminal->TrySnapOnInput();
_terminal->WritePastedText(wstr);
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is very satisfying 🎉

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Glad! 😁

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I decided to keep the other terminal operations in this method to make WritePastedText more lightweight and decoupling from non-paste-related things. WDYT?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure! I was wondering if the other two operations are something the Core should handle too.

@zadjii-msft if we want Core to be reusable, should it be given more responsibilities for figuring out when to clear the selection and snap on input? I feel like it should -- so maybe we should move the two lines under WritePastedText into WritePastedText. What do you think?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea I agree, that should probably move down below too. That makes sense. Doesn't make sense to block this PR over it though, IMO. We could probably just get away with

Suggested change
_terminal->WritePastedText(wstr);
// TODO:projects/5 The calls to ClearSelection and TrySnapOnInput below could probably get moved inside Terminal::WritePastedText.
_terminal->WritePastedText(wstr);

and have me come back to it 😛

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh the bot automerged it. Whoops. I'm sure this whole area's about to be torn up anyways

src/types/utils.cpp Outdated Show resolved Hide resolved
src/types/utils.cpp Outdated Show resolved Hide resolved
@skyline75489
Copy link
Collaborator Author

skyline75489 commented Feb 7, 2021

OK this is ready, I think. There's more to do:

  1. Make ConPTY passthrough bracketed paste related sequences (See bracketed paste in conhost #395 (comment)).
  2. Make a setting for filtering control codes
  3. Maybe also a setting entry for bracketed paste? (Who wouldn't want the feature though)
  4. Backport brackted paste mode to conhost.exe

All of the above are not really my comfort zone. I don't know conpty or settings model that well. I guess we can track them in the bracketed paste main issue for future work.

@DHowett
Copy link
Member

DHowett commented Feb 8, 2021

OK this is ready, I think. There's more to do:

  1. Make ConPTY passthrough bracketed paste related sequences (See #395 (comment)).

DECSET 2004 request: If conhost's dispatcher returns false for EnableXtermBracketedPasteMode, it will pass through the request automatically. #8840 did this correctly.

200~ and 201~ in the input stream: In ENABLE_VIRTUAL_TERMINAL_INPUT mode, the bracketed paste sequences will automatically be passed through from the terminal to the client (we skip a lot of ConPTY input processing when VT input is on)

  1. Make a setting for filtering control codes

We should only do this if more than one person asks for it. Jantari is the first; will there be a second?

  1. Maybe also a setting entry for bracketed paste? (Who wouldn't want the feature though)

Nope. Not unless somebody complains.

  1. Backport brackted paste mode to conhost.exe

I'd like to handle this myself as part of the input stack change. Is that okay? 😄

All of the above are not really my comfort zone. I don't know conpty or settings model that well. I guess we can track them in the bracketed paste main issue for future work.

Not a problem! I feel like you don't have too much work to do, given the above notes.

Thanks again for doing this!

Copy link
Member

@DHowett DHowett left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks excellent to me. Thank you.


_terminal->ClearSelection();
_terminal->TrySnapOnInput();
_terminal->WritePastedText(wstr);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure! I was wondering if the other two operations are something the Core should handle too.

@zadjii-msft if we want Core to be reusable, should it be given more responsibilities for figuring out when to clear the selection and snap on input? I feel like it should -- so maybe we should move the two lines under WritePastedText into WritePastedText. What do you think?

filtered.append(L"\x1b[201~");
}

if (_pfnWriteInput)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: we don't need to do any of this work if there is no _pfnWriteInput ! 😁

::Microsoft::Console::Utils::FilterOption::ControlCodes;

std::wstring filtered = ::Microsoft::Console::Utils::FilterStringForPaste(stringView, option);
if (IsXtermBracketedPasteModeEnabled())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here's an idea. Maybe to handle Jantari's case (since they want to paste literal control sequences), we can strip control codes only when bracketed paste mode is enabled.

@j4james, do you think that's a reasonable compromise? It solves the case where a clipboard payload can break out of bracketed paste and doesn't make unguarded paste any worse.

At the same time, I still can't see the value in pasting raw control codes here today in Common Era 2021, so...

The only time I ever did it was when I was actively trying to blow up bracketed paste in xterm/rxvt.

Otherwise, that's what ^V is for.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Personally, my vote is let's strip them always.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like to just strip them always, too. Also I don't like the idea of coupling "control codes filtering" and "bracketed paste mode". This is what @j4james told me specifically not to do in #7508 (comment)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the record, I'm in agreement with you guys. I think it's preferable that they're always filtered.

@DHowett
Copy link
Member

DHowett commented Feb 8, 2021

@msftbot make sure @zadjii-msft signs off

@ghost ghost added the AutoMerge Marked for automatic merge by the bot when requirements are met label Feb 8, 2021
@ghost
Copy link

ghost commented Feb 8, 2021

Hello @DHowett!

Because you've given me some instructions on how to help merge this pull request, I'll be modifying my merge approach. Here's how I understand your requirements for merging this pull request:

  • I'll only merge this pull request if it's approved by @zadjii-msft

If this doesn't seem right to you, you can tell me to cancel these instructions and use the auto-merge policy that has been configured for this repository. Try telling me "forget everything I just told you".

Copy link
Member

@zadjii-msft zadjii-msft left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This all seems good to me. Not sure how many times we've reviewed it now haha. I'm not gonna block over a nit comment


_terminal->ClearSelection();
_terminal->TrySnapOnInput();
_terminal->WritePastedText(wstr);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea I agree, that should probably move down below too. That makes sense. Doesn't make sense to block this PR over it though, IMO. We could probably just get away with

Suggested change
_terminal->WritePastedText(wstr);
// TODO:projects/5 The calls to ClearSelection and TrySnapOnInput below could probably get moved inside Terminal::WritePastedText.
_terminal->WritePastedText(wstr);

and have me come back to it 😛

@ghost ghost merged commit 2c603ef into microsoft:main Feb 8, 2021
@skyline75489
Copy link
Collaborator Author

@DHowett Reading your comments regarding my list of future work just make me realize I really do not know ConPTY & conhost.exe related infrastructure that well 😅 . But I can sleep at night knowing it's in good hands of you & @zadjii-msft .

@ghost
Copy link

ghost commented Mar 1, 2021

🎉Windows Terminal Preview v1.7.572.0 has been released which incorporates this pull request.:tada:

Handy links:

@mnpenner
Copy link

mnpenner commented Mar 2, 2021

I was going to ask how we can disable the warning now that we have bracketed paste mode; good thing I searched first 😆 Answer is here for anyone else wondering. Documented here.

@skyline75489
Copy link
Collaborator Author

@mnpenner If you want the terminal to be more "smart" about this, check out #9586 which is available now in 1.8 Preview.

DHowett pushed a commit that referenced this pull request Apr 26, 2023
This adds support for XTerm's "bracketed paste" mode in ConHost. When
enabled, any pasted text is bracketed with a pair of escape sequences,
which lets the receiving application know that the content was pasted
rather than typed.

## References and Relevant Issues

Bracketed paste mode was added to Windows Terminal in PR #9034.
Adding it to ConHost ticks one more item off the list in #13408. 

## Detailed Description of the Pull Request / Additional comments

This only applies when VT input mode is enabled, since that is the way
Windows Terminal currently works.

When it comes to filtering, though, the only change I've made is to
filter out the escape character, and only when bracketed mode is
enabled. That's necessary to prevent any attempts to bypass the
bracketing, but I didn't want to mess with the expected behavior for
legacy apps if bracketed mode is disabled.

## Validation Steps Performed

Manually tested in bash with `bind 'set enable-bracketed-paste on'` and
confirmed that pasted content is now buffered, instead of being executed
immediately.

Also tested in VIM, and confirmed that you can now paste preformatted
code without the autoindent breaking the formatting.

Closes #395
This pull request was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-VT Virtual Terminal sequence support AutoMerge Marked for automatic merge by the bot when requirements are met Issue-Feature Complex enough to require an in depth planning process and actual budgeted, scheduled work. Product-Conhost For issues in the Console codebase
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants