mirror of
https://github.com/microsoft/terminal.git
synced 2025-12-19 09:58:08 -05:00
Use Char[] for Connection stdin (#19655)
This makes it possible to pass through non-null-terminated strings. This is needed for the tmux control mode which passes string slices.
This commit is contained in:
@@ -120,9 +120,9 @@ namespace winrt::Microsoft::TerminalApp::implementation
|
|||||||
return ConnectionState::Failed;
|
return ConnectionState::Failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebugTapConnection::_OutputHandler(const std::wstring_view str)
|
void DebugTapConnection::_OutputHandler(const winrt::array_view<const char16_t> str)
|
||||||
{
|
{
|
||||||
auto output = til::visualize_control_codes(str);
|
auto output = til::visualize_control_codes(winrt_array_to_wstring_view(str));
|
||||||
// To make the output easier to read, we introduce a line break whenever
|
// To make the output easier to read, we introduce a line break whenever
|
||||||
// an LF control is encountered. But at this point, the LF would have
|
// an LF control is encountered. But at this point, the LF would have
|
||||||
// been converted to U+240A (␊), so that's what we need to search for.
|
// been converted to U+240A (␊), so that's what we need to search for.
|
||||||
@@ -130,7 +130,7 @@ namespace winrt::Microsoft::TerminalApp::implementation
|
|||||||
{
|
{
|
||||||
output.insert(++lfPos, L"\r\n");
|
output.insert(++lfPos, L"\r\n");
|
||||||
}
|
}
|
||||||
TerminalOutput.raise(output);
|
TerminalOutput.raise(winrt_wstring_to_array_view(output));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called by the DebugInputTapConnection to print user input
|
// Called by the DebugInputTapConnection to print user input
|
||||||
@@ -138,7 +138,7 @@ namespace winrt::Microsoft::TerminalApp::implementation
|
|||||||
{
|
{
|
||||||
auto clean{ til::visualize_control_codes(str) };
|
auto clean{ til::visualize_control_codes(str) };
|
||||||
auto formatted{ wil::str_printf<std::wstring>(L"\x1b[91m%ls\x1b[m", clean.data()) };
|
auto formatted{ wil::str_printf<std::wstring>(L"\x1b[91m%ls\x1b[m", clean.data()) };
|
||||||
TerminalOutput.raise(formatted);
|
TerminalOutput.raise(winrt_wstring_to_array_view(formatted));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wire us up so that we can forward input through
|
// Wire us up so that we can forward input through
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ namespace winrt::Microsoft::TerminalApp::implementation
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void _PrintInput(const std::wstring_view data);
|
void _PrintInput(const std::wstring_view data);
|
||||||
void _OutputHandler(const std::wstring_view str);
|
void _OutputHandler(const winrt::array_view<const char16_t> str);
|
||||||
|
|
||||||
winrt::Microsoft::Terminal::TerminalConnection::ITerminalConnection::TerminalOutput_revoker _outputRevoker;
|
winrt::Microsoft::Terminal::TerminalConnection::ITerminalConnection::TerminalOutput_revoker _outputRevoker;
|
||||||
winrt::Microsoft::Terminal::TerminalConnection::ITerminalConnection::StateChanged_revoker _stateChangedRevoker;
|
winrt::Microsoft::Terminal::TerminalConnection::ITerminalConnection::StateChanged_revoker _stateChangedRevoker;
|
||||||
|
|||||||
@@ -94,9 +94,15 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
|||||||
// - helper that will write an unterminated string (generally, from a resource) to the output stream.
|
// - helper that will write an unterminated string (generally, from a resource) to the output stream.
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// - str: the string to write.
|
// - str: the string to write.
|
||||||
|
void AzureConnection::_WriteStringWithNewline(std::wstring str)
|
||||||
|
{
|
||||||
|
str.append(L"\r\n");
|
||||||
|
TerminalOutput.raise(winrt_wstring_to_array_view(str));
|
||||||
|
}
|
||||||
|
|
||||||
void AzureConnection::_WriteStringWithNewline(const std::wstring_view str)
|
void AzureConnection::_WriteStringWithNewline(const std::wstring_view str)
|
||||||
{
|
{
|
||||||
TerminalOutput.raise(str + L"\r\n");
|
TerminalOutput.raise(winrt_wstring_to_array_view(str + L"\r\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method description:
|
// Method description:
|
||||||
@@ -112,7 +118,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
|||||||
catch (const std::exception& runtimeException)
|
catch (const std::exception& runtimeException)
|
||||||
{
|
{
|
||||||
// This also catches the AzureException, which has a .what()
|
// This also catches the AzureException, which has a .what()
|
||||||
TerminalOutput.raise(_colorize(91, til::u8u16(std::string{ runtimeException.what() })));
|
TerminalOutput.raise(winrt_wstring_to_array_view(_colorize(91, til::u8u16(std::string{ runtimeException.what() }))));
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
@@ -162,13 +168,13 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
|||||||
|
|
||||||
_currentInputMode = mode;
|
_currentInputMode = mode;
|
||||||
|
|
||||||
TerminalOutput.raise(L"> \x1b[92m"); // Make prompted user input green
|
TerminalOutput.raise(winrt_wstring_to_array_view(L"> \x1b[92m")); // Make prompted user input green
|
||||||
|
|
||||||
_inputEvent.wait(inputLock, [this, mode]() {
|
_inputEvent.wait(inputLock, [this, mode]() {
|
||||||
return _currentInputMode != mode || _isStateAtOrBeyond(ConnectionState::Closing);
|
return _currentInputMode != mode || _isStateAtOrBeyond(ConnectionState::Closing);
|
||||||
});
|
});
|
||||||
|
|
||||||
TerminalOutput.raise(L"\x1b[m");
|
TerminalOutput.raise(winrt_wstring_to_array_view(L"\x1b[m"));
|
||||||
|
|
||||||
if (_isStateAtOrBeyond(ConnectionState::Closing))
|
if (_isStateAtOrBeyond(ConnectionState::Closing))
|
||||||
{
|
{
|
||||||
@@ -211,19 +217,19 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
|||||||
if (_userInput.size() > 0)
|
if (_userInput.size() > 0)
|
||||||
{
|
{
|
||||||
_userInput.pop_back();
|
_userInput.pop_back();
|
||||||
TerminalOutput.raise(L"\x08 \x08"); // overstrike the character with a space
|
TerminalOutput.raise(winrt_wstring_to_array_view(L"\x08 \x08")); // overstrike the character with a space
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
TerminalOutput.raise(data); // echo back
|
TerminalOutput.raise(winrt_wstring_to_array_view(data)); // echo back
|
||||||
|
|
||||||
switch (_currentInputMode)
|
switch (_currentInputMode)
|
||||||
{
|
{
|
||||||
case InputMode::Line:
|
case InputMode::Line:
|
||||||
if (data.size() > 0 && gsl::at(data, 0) == UNICODE_CARRIAGERETURN)
|
if (data.size() > 0 && gsl::at(data, 0) == UNICODE_CARRIAGERETURN)
|
||||||
{
|
{
|
||||||
TerminalOutput.raise(L"\r\n"); // we probably got a \r, so we need to advance to the next line.
|
TerminalOutput.raise(winrt_wstring_to_array_view(L"\r\n")); // we probably got a \r, so we need to advance to the next line.
|
||||||
_currentInputMode = InputMode::None; // toggling the mode indicates completion
|
_currentInputMode = InputMode::None; // toggling the mode indicates completion
|
||||||
_inputEvent.notify_one();
|
_inputEvent.notify_one();
|
||||||
break;
|
break;
|
||||||
@@ -429,7 +435,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Pass the output to our registered event handlers
|
// Pass the output to our registered event handlers
|
||||||
TerminalOutput.raise(_u16Str);
|
TerminalOutput.raise(winrt_wstring_to_array_view(_u16Str));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case WINHTTP_WEB_SOCKET_CLOSE_BUFFER_TYPE:
|
case WINHTTP_WEB_SOCKET_CLOSE_BUFFER_TYPE:
|
||||||
@@ -772,7 +778,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
|||||||
const auto shellType = _ParsePreferredShellType(settingsResponse);
|
const auto shellType = _ParsePreferredShellType(settingsResponse);
|
||||||
_WriteStringWithNewline(RS_(L"AzureRequestingTerminal"));
|
_WriteStringWithNewline(RS_(L"AzureRequestingTerminal"));
|
||||||
const auto socketUri = _GetTerminal(shellType);
|
const auto socketUri = _GetTerminal(shellType);
|
||||||
TerminalOutput.raise(L"\r\n");
|
TerminalOutput.raise(winrt_wstring_to_array_view(L"\r\n"));
|
||||||
|
|
||||||
//// Step 8: connecting to said terminal
|
//// Step 8: connecting to said terminal
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
|||||||
std::optional<::Microsoft::Terminal::Azure::Tenant> _currentTenant;
|
std::optional<::Microsoft::Terminal::Azure::Tenant> _currentTenant;
|
||||||
|
|
||||||
void _writeInput(const std::wstring_view str);
|
void _writeInput(const std::wstring_view str);
|
||||||
|
void _WriteStringWithNewline(std::wstring str);
|
||||||
void _WriteStringWithNewline(const std::wstring_view str);
|
void _WriteStringWithNewline(const std::wstring_view str);
|
||||||
void _WriteCaughtExceptionRecord();
|
void _WriteCaughtExceptionRecord();
|
||||||
winrt::Windows::Data::Json::JsonObject _SendRequestReturningJson(std::wstring_view uri, const winrt::Windows::Web::Http::IHttpContent& content = nullptr, winrt::Windows::Web::Http::HttpMethod method = nullptr, const winrt::Windows::Foundation::Uri referer = nullptr);
|
winrt::Windows::Data::Json::JsonObject _SendRequestReturningJson(std::wstring_view uri, const winrt::Windows::Web::Http::IHttpContent& content = nullptr, winrt::Windows::Web::Http::HttpMethod method = nullptr, const winrt::Windows::Foundation::Uri referer = nullptr);
|
||||||
|
|||||||
@@ -477,31 +477,28 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
|||||||
const auto hr = wil::ResultFromCaughtException();
|
const auto hr = wil::ResultFromCaughtException();
|
||||||
|
|
||||||
// GH#11556 - make sure to format the error code to this string as an UNSIGNED int
|
// GH#11556 - make sure to format the error code to this string as an UNSIGNED int
|
||||||
const auto failureText = RS_fmt(L"ProcessFailedToLaunch", _formatStatus(hr), _commandline);
|
auto failureText = RS_fmt(L"ProcessFailedToLaunch", _formatStatus(hr), _commandline);
|
||||||
TerminalOutput.raise(failureText);
|
|
||||||
|
|
||||||
// If the path was invalid, let's present an informative message to the user
|
// If the path was invalid, let's present an informative message to the user
|
||||||
if (hr == HRESULT_FROM_WIN32(ERROR_DIRECTORY))
|
if (hr == HRESULT_FROM_WIN32(ERROR_DIRECTORY))
|
||||||
{
|
{
|
||||||
const auto badPathText = RS_fmt(L"BadPathText", _startingDirectory);
|
failureText.append(L"\r\n");
|
||||||
TerminalOutput.raise(L"\r\n");
|
failureText.append(RS_fmt(L"BadPathText", _startingDirectory));
|
||||||
TerminalOutput.raise(badPathText);
|
|
||||||
}
|
}
|
||||||
// If the requested action requires elevation, display appropriate message
|
// If the requested action requires elevation, display appropriate message
|
||||||
else if (hr == HRESULT_FROM_WIN32(ERROR_ELEVATION_REQUIRED))
|
else if (hr == HRESULT_FROM_WIN32(ERROR_ELEVATION_REQUIRED))
|
||||||
{
|
{
|
||||||
const auto elevationText = RS_(L"ElevationRequired");
|
failureText.append(L"\r\n");
|
||||||
TerminalOutput.raise(L"\r\n");
|
failureText.append(RS_(L"ElevationRequired"));
|
||||||
TerminalOutput.raise(elevationText);
|
|
||||||
}
|
}
|
||||||
// If the requested executable was not found, display appropriate message
|
// If the requested executable was not found, display appropriate message
|
||||||
else if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND))
|
else if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND))
|
||||||
{
|
{
|
||||||
const auto fileNotFoundText = RS_(L"FileNotFound");
|
failureText.append(L"\r\n");
|
||||||
TerminalOutput.raise(L"\r\n");
|
failureText.append(RS_(L"FileNotFound"));
|
||||||
TerminalOutput.raise(fileNotFoundText);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TerminalOutput.raise(winrt_wstring_to_array_view(failureText));
|
||||||
_transitionToState(ConnectionState::Failed);
|
_transitionToState(ConnectionState::Failed);
|
||||||
|
|
||||||
// Tear down any state we may have accumulated.
|
// Tear down any state we may have accumulated.
|
||||||
@@ -520,7 +517,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
|||||||
const auto msg1 = RS_fmt(L"ProcessExited", _formatStatus(status));
|
const auto msg1 = RS_fmt(L"ProcessExited", _formatStatus(status));
|
||||||
const auto msg2 = RS_(L"CtrlDToClose");
|
const auto msg2 = RS_(L"CtrlDToClose");
|
||||||
const auto msg = fmt::format(FMT_COMPILE(L"\r\n{}\r\n{}\r\n"), msg1, msg2);
|
const auto msg = fmt::format(FMT_COMPILE(L"\r\n{}\r\n{}\r\n"), msg1, msg2);
|
||||||
TerminalOutput.raise(msg);
|
TerminalOutput.raise(winrt_wstring_to_array_view(msg));
|
||||||
}
|
}
|
||||||
CATCH_LOG();
|
CATCH_LOG();
|
||||||
}
|
}
|
||||||
@@ -792,7 +789,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
TerminalOutput.raise(wstr);
|
TerminalOutput.raise(winrt_wstring_to_array_view(wstr));
|
||||||
}
|
}
|
||||||
CATCH_LOG();
|
CATCH_LOG();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
|||||||
prettyPrint << wch;
|
prettyPrint << wch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TerminalOutput.raise(prettyPrint.str());
|
TerminalOutput.raise(winrt_wstring_to_array_view(prettyPrint.str()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void EchoConnection::Resize(uint32_t /*rows*/, uint32_t /*columns*/) noexcept
|
void EchoConnection::Resize(uint32_t /*rows*/, uint32_t /*columns*/) noexcept
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ namespace Microsoft.Terminal.TerminalConnection
|
|||||||
Failed
|
Failed
|
||||||
};
|
};
|
||||||
|
|
||||||
delegate void TerminalOutputHandler(String output);
|
delegate void TerminalOutputHandler(Char[] output);
|
||||||
|
|
||||||
interface ITerminalConnection
|
interface ITerminalConnection
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -10,8 +10,6 @@
|
|||||||
|
|
||||||
#include <DefaultSettings.h>
|
#include <DefaultSettings.h>
|
||||||
#include <unicode.hpp>
|
#include <unicode.hpp>
|
||||||
#include <utils.hpp>
|
|
||||||
#include <WinUser.h>
|
|
||||||
|
|
||||||
#include "EventArgs.h"
|
#include "EventArgs.h"
|
||||||
#include "../../renderer/atlas/AtlasEngine.h"
|
#include "../../renderer/atlas/AtlasEngine.h"
|
||||||
@@ -2238,13 +2236,13 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||||||
auto noticeArgs = winrt::make<NoticeEventArgs>(NoticeLevel::Info, RS_(L"TermControlReadOnly"));
|
auto noticeArgs = winrt::make<NoticeEventArgs>(NoticeLevel::Info, RS_(L"TermControlReadOnly"));
|
||||||
RaiseNotice.raise(*this, std::move(noticeArgs));
|
RaiseNotice.raise(*this, std::move(noticeArgs));
|
||||||
}
|
}
|
||||||
void ControlCore::_connectionOutputHandler(const hstring& hstr)
|
void ControlCore::_connectionOutputHandler(const winrt::array_view<const char16_t> str)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
const auto lock = _terminal->LockForWriting();
|
const auto lock = _terminal->LockForWriting();
|
||||||
_terminal->Write(hstr);
|
_terminal->Write(winrt_array_to_wstring_view(str));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_pendingResponses.empty())
|
if (!_pendingResponses.empty())
|
||||||
|
|||||||
@@ -349,7 +349,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||||||
|
|
||||||
void _raiseReadOnlyWarning();
|
void _raiseReadOnlyWarning();
|
||||||
void _updateAntiAliasingMode();
|
void _updateAntiAliasingMode();
|
||||||
void _connectionOutputHandler(const hstring& hstr);
|
void _connectionOutputHandler(winrt::array_view<const char16_t> str);
|
||||||
void _connectionStateChangedHandler(const TerminalConnection::ITerminalConnection&, const Windows::Foundation::IInspectable&);
|
void _connectionStateChangedHandler(const TerminalConnection::ITerminalConnection&, const Windows::Foundation::IInspectable&);
|
||||||
void _updateHoveredCell(const std::optional<til::point> terminalPosition);
|
void _updateHoveredCell(const std::optional<til::point> terminalPosition);
|
||||||
void _setOpacity(const float opacity, const bool focused = true);
|
void _setOpacity(const float opacity, const bool focused = true);
|
||||||
|
|||||||
@@ -28,10 +28,11 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
|||||||
{
|
{
|
||||||
PreviewConnection::PreviewConnection() noexcept = default;
|
PreviewConnection::PreviewConnection() noexcept = default;
|
||||||
|
|
||||||
void PreviewConnection::Start() noexcept
|
void PreviewConnection::Start()
|
||||||
{
|
{
|
||||||
// Send the preview text
|
const auto prompt = _displayPowerlineGlyphs ? PromptTextPowerline : PromptTextPlain;
|
||||||
TerminalOutput.raise(fmt::format(PreviewText, _displayPowerlineGlyphs ? PromptTextPowerline : PromptTextPlain));
|
const auto text = fmt::format(FMT_COMPILE(PreviewText), prompt);
|
||||||
|
TerminalOutput.raise(winrt_wstring_to_array_view(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
void PreviewConnection::Initialize(const Windows::Foundation::Collections::ValueSet& /*settings*/) noexcept
|
void PreviewConnection::Initialize(const Windows::Foundation::Collections::ValueSet& /*settings*/) noexcept
|
||||||
@@ -50,7 +51,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void PreviewConnection::DisplayPowerlineGlyphs(bool d) noexcept
|
void PreviewConnection::DisplayPowerlineGlyphs(bool d)
|
||||||
{
|
{
|
||||||
if (_displayPowerlineGlyphs != d)
|
if (_displayPowerlineGlyphs != d)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -22,12 +22,12 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
|||||||
PreviewConnection() noexcept;
|
PreviewConnection() noexcept;
|
||||||
|
|
||||||
void Initialize(const Windows::Foundation::Collections::ValueSet& settings) noexcept;
|
void Initialize(const Windows::Foundation::Collections::ValueSet& settings) noexcept;
|
||||||
void Start() noexcept;
|
void Start();
|
||||||
void WriteInput(const winrt::array_view<const char16_t> buffer);
|
void WriteInput(const winrt::array_view<const char16_t> buffer);
|
||||||
void Resize(uint32_t rows, uint32_t columns) noexcept;
|
void Resize(uint32_t rows, uint32_t columns) noexcept;
|
||||||
void Close() noexcept;
|
void Close() noexcept;
|
||||||
|
|
||||||
void DisplayPowerlineGlyphs(bool d) noexcept;
|
void DisplayPowerlineGlyphs(bool d);
|
||||||
|
|
||||||
winrt::guid SessionId() const noexcept { return {}; }
|
winrt::guid SessionId() const noexcept { return {}; }
|
||||||
winrt::Microsoft::Terminal::TerminalConnection::ConnectionState State() const noexcept { return winrt::Microsoft::Terminal::TerminalConnection::ConnectionState::Connected; }
|
winrt::Microsoft::Terminal::TerminalConnection::ConnectionState State() const noexcept { return winrt::Microsoft::Terminal::TerminalConnection::ConnectionState::Connected; }
|
||||||
|
|||||||
@@ -104,13 +104,14 @@ namespace ControlUnitTests
|
|||||||
auto _addInputCallback(const winrt::com_ptr<MockConnection>& conn,
|
auto _addInputCallback(const winrt::com_ptr<MockConnection>& conn,
|
||||||
std::deque<std::wstring>& expectedOutput)
|
std::deque<std::wstring>& expectedOutput)
|
||||||
{
|
{
|
||||||
conn->TerminalOutput([&](const hstring& hstr) {
|
conn->TerminalOutput([&](const winrt::array_view<const char16_t> str) {
|
||||||
VERIFY_IS_GREATER_THAN(expectedOutput.size(), 0u);
|
VERIFY_IS_GREATER_THAN(expectedOutput.size(), 0u);
|
||||||
|
const auto actual = winrt_array_to_wstring_view(str);
|
||||||
const auto expected = expectedOutput.front();
|
const auto expected = expectedOutput.front();
|
||||||
expectedOutput.pop_front();
|
expectedOutput.pop_front();
|
||||||
Log::Comment(fmt::format(L"Received: \"{}\"", TerminalCoreUnitTests::TestUtils::ReplaceEscapes(hstr.c_str())).c_str());
|
Log::Comment(fmt::format(L"Received: \"{}\"", til::visualize_nonspace_control_codes(std::wstring{ actual })).c_str());
|
||||||
Log::Comment(fmt::format(L"Expected: \"{}\"", TerminalCoreUnitTests::TestUtils::ReplaceEscapes(expected)).c_str());
|
Log::Comment(fmt::format(L"Expected: \"{}\"", til::visualize_nonspace_control_codes(expected)).c_str());
|
||||||
VERIFY_ARE_EQUAL(expected, hstr);
|
VERIFY_ARE_EQUAL(expected, actual);
|
||||||
});
|
});
|
||||||
|
|
||||||
return std::move(wil::scope_exit([&]() {
|
return std::move(wil::scope_exit([&]() {
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ namespace ControlUnitTests
|
|||||||
void Start() noexcept {};
|
void Start() noexcept {};
|
||||||
void WriteInput(const winrt::array_view<const char16_t> data)
|
void WriteInput(const winrt::array_view<const char16_t> data)
|
||||||
{
|
{
|
||||||
TerminalOutput.raise(winrt_array_to_wstring_view(data));
|
TerminalOutput.raise(data);
|
||||||
}
|
}
|
||||||
void Resize(uint32_t /*rows*/, uint32_t /*columns*/) noexcept {}
|
void Resize(uint32_t /*rows*/, uint32_t /*columns*/) noexcept {}
|
||||||
void Close() noexcept {}
|
void Close() noexcept {}
|
||||||
|
|||||||
@@ -109,50 +109,6 @@ public:
|
|||||||
return iter;
|
return iter;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Function Description:
|
|
||||||
// - Replaces all escapes with the printable symbol for that escape
|
|
||||||
// character. This makes log parsing easier for debugging, as the literal
|
|
||||||
// escapes won't be written to the console output.
|
|
||||||
// Arguments:
|
|
||||||
// - str: the string to escape.
|
|
||||||
// Return Value:
|
|
||||||
// - A modified version of that string with non-printable characters replaced.
|
|
||||||
static std::string ReplaceEscapes(const std::string& str)
|
|
||||||
{
|
|
||||||
std::string escaped = str;
|
|
||||||
auto replaceFn = [&escaped](const std::string& search, const std::string& replace) {
|
|
||||||
size_t pos = escaped.find(search, 0);
|
|
||||||
while (pos != std::string::npos)
|
|
||||||
{
|
|
||||||
escaped.replace(pos, search.length(), replace);
|
|
||||||
pos = escaped.find(search, pos + replace.length());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
replaceFn("\x1b", "^\x5b"); // ESC
|
|
||||||
replaceFn("\x08", "^\x48"); // BS
|
|
||||||
replaceFn("\x0A", "^\x4A"); // LF
|
|
||||||
replaceFn("\x0D", "^\x4D"); // CR
|
|
||||||
return escaped;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Function Description:
|
|
||||||
// - Replaces all escapes with the printable symbol for that escape
|
|
||||||
// character. This makes log parsing easier for debugging, as the literal
|
|
||||||
// escapes won't be written to the console output.
|
|
||||||
// Arguments:
|
|
||||||
// - wstr: the string to escape.
|
|
||||||
// Return Value:
|
|
||||||
// - A modified version of that string with non-printable characters replaced.
|
|
||||||
static std::wstring ReplaceEscapes(const std::wstring& wstr)
|
|
||||||
{
|
|
||||||
std::wstring escaped = wstr;
|
|
||||||
std::replace(escaped.begin(), escaped.end(), L'\x1b', L'\x241b'); // ESC
|
|
||||||
std::replace(escaped.begin(), escaped.end(), L'\x08', L'\x2408'); // BS
|
|
||||||
std::replace(escaped.begin(), escaped.end(), L'\x0A', L'\x240A'); // LF
|
|
||||||
std::replace(escaped.begin(), escaped.end(), L'\x0D', L'\x240D'); // CR
|
|
||||||
return escaped;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class... T>
|
template<class... T>
|
||||||
static bool VerifyLineContains(TextBufferCellIterator& actual, T&&... expectedContent)
|
static bool VerifyLineContains(TextBufferCellIterator& actual, T&&... expectedContent)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user