Fix multi line paste detection and filtering (#8634)
- Detect `\r` when warning about multi line paste - Translate `\n` to `\r` on paste ## PR Checklist * [x] Closes #8601 * [x] Closes #5821 ## Validation Steps Performed Manual testing
This commit is contained in:
parent
8bef5eefd5
commit
49d008537f
|
@ -1935,8 +1935,9 @@ namespace winrt::TerminalApp::implementation
|
|||
}
|
||||
}
|
||||
|
||||
const bool hasNewLine = std::find(text.cbegin(), text.cend(), L'\n') != text.cend();
|
||||
const bool warnMultiLine = hasNewLine && _settings.GlobalSettings().WarnAboutMultiLinePaste();
|
||||
const auto isNewLineLambda = [](auto c) { return c == L'\n' || c == L'\r'; };
|
||||
const auto hasNewLine = std::find_if(text.cbegin(), text.cend(), isNewLineLambda) != text.cend();
|
||||
const auto warnMultiLine = hasNewLine && _settings.GlobalSettings().WarnAboutMultiLinePaste();
|
||||
|
||||
constexpr const std::size_t minimumSizeForWarning = 1024 * 5; // 5 KiB
|
||||
const bool warnLargeText = text.size() > minimumSizeForWarning &&
|
||||
|
|
|
@ -2025,6 +2025,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
|||
// - Pre-process text pasted (presumably from the clipboard)
|
||||
// before sending it over the terminal's connection, converting
|
||||
// Windows-space \r\n line-endings to \r line-endings
|
||||
// - Also converts \n line-endings to \r line-endings
|
||||
void TermControl::_SendPastedTextToConnection(const std::wstring& wstr)
|
||||
{
|
||||
// Some notes on this implementation:
|
||||
|
@ -2034,20 +2035,51 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
|||
// performance guarantees aren't exactly stellar)
|
||||
// - The STL doesn't have a simple string search/replace method.
|
||||
// This fact is lamentable.
|
||||
// - This line-ending conversion is intentionally fairly
|
||||
// conservative, to avoid stripping out lone \n characters
|
||||
// where they could conceivably be intentional.
|
||||
// - We search for \n, and when we find it we copy the string up to
|
||||
// the \n (but not including it). Then, we check the if the
|
||||
// previous character is \r, if its not, then we had a lone \n
|
||||
// and so we append our own \r
|
||||
|
||||
std::wstring stripped{ wstr };
|
||||
std::wstring stripped;
|
||||
stripped.reserve(wstr.length());
|
||||
|
||||
std::wstring::size_type pos = 0;
|
||||
std::wstring::size_type begin = 0;
|
||||
|
||||
while ((pos = stripped.find(L"\r\n", pos)) != std::wstring::npos)
|
||||
while ((pos = wstr.find(L"\n", pos)) != std::wstring::npos)
|
||||
{
|
||||
stripped.replace(pos, 2, L"\r");
|
||||
// copy up to but not including the \n
|
||||
stripped.append(wstr.cbegin() + begin, wstr.cbegin() + pos);
|
||||
if (!(pos > 0 && (wstr.at(pos - 1) == L'\r')))
|
||||
{
|
||||
// there was no \r before the \n we did not copy,
|
||||
// so append our own \r (this effectively replaces the \n
|
||||
// with a \r)
|
||||
stripped.push_back(L'\r');
|
||||
}
|
||||
++pos;
|
||||
begin = pos;
|
||||
}
|
||||
|
||||
// If we entered the while loop even once, begin would be non-zero
|
||||
// (because we set begin = pos right after incrementing pos)
|
||||
// So, if begin is still zero at this point it means we never found a newline
|
||||
// and we can just write the original string
|
||||
if (begin == 0)
|
||||
{
|
||||
_connection.WriteInput(wstr);
|
||||
}
|
||||
else
|
||||
{
|
||||
// copy over the part after the last \n
|
||||
stripped.append(wstr.cbegin() + begin, wstr.cend());
|
||||
|
||||
// we may have removed some characters, so we may not need as much space
|
||||
// as we reserved earlier
|
||||
stripped.shrink_to_fit();
|
||||
_connection.WriteInput(stripped);
|
||||
}
|
||||
|
||||
_connection.WriteInput(stripped);
|
||||
_terminal->TrySnapOnInput();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue