From 9ab2870bc37b49898f00d8890be4184a8af946a1 Mon Sep 17 00:00:00 2001 From: Leonard Hecker Date: Fri, 9 Aug 2024 00:40:05 +0200 Subject: [PATCH] Upgrade fmt to 11.0.2 (#16007) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Between fmt 7.1.3 and 11.0.2 a lot has happened. `wchar_t` support is now more limited and implicit conversions don't work anymore. Furthermore, even the non-`FMT_COMPILE` API is now compile-time checked and so it fails to work in our UI code which passes `hstring` format strings which aren't implicitly convertible to the expected type. `fmt::runtime` was introduced for this but it also fails to work for `hstring` parameters. To solve this, a new `RS_fmt` macro was added to abstract the added `std::wstring_view` casting away. Finally, some additional changes to reduce `stringstream` usage have been made, whenever `format_to`, etc., is available. This mostly affects `ActionArgs.cpp`. Closes #16000 ## Validation Steps Performed * Compiles ✅ * Settings page opens ✅ --- .github/actions/spelling/expect/expect.txt | 3 +- .../TerminalApp/AppActionHandlers.cpp | 10 +- src/cascadia/TerminalApp/AppLogic.cpp | 2 +- src/cascadia/TerminalApp/CommandPalette.cpp | 4 +- src/cascadia/TerminalApp/Jumplist.cpp | 2 +- .../TerminalApp/SnippetsPaneContent.h | 2 +- .../TerminalApp/SuggestionsControl.cpp | 4 +- src/cascadia/TerminalApp/TabManagement.cpp | 2 +- src/cascadia/TerminalApp/TerminalPage.cpp | 18 +- src/cascadia/TerminalApp/TerminalTab.cpp | 2 +- src/cascadia/TerminalApp/TerminalWindow.cpp | 4 +- .../TerminalConnection/AzureConnection.cpp | 31 +- .../TerminalConnection/ConptyConnection.cpp | 20 +- .../TerminalConnection/ConptyConnection.h | 1 + .../TerminalControl/SearchBoxControl.cpp | 6 +- src/cascadia/TerminalControl/TermControl.cpp | 11 +- .../ColorSchemeViewModel.cpp | 2 +- .../ColorSchemesPageViewModel.cpp | 2 +- .../LaunchViewModel.cpp | 10 +- .../SettingContainer.cpp | 2 +- .../TerminalSettingsModel/ActionAndArgs.cpp | 45 ++- .../TerminalSettingsModel/ActionAndArgs.h | 1 - .../TerminalSettingsModel/ActionArgs.cpp | 318 +++++++----------- .../TerminalSettingsModel/ActionMap.cpp | 2 +- .../CascadiaSettings.cpp | 6 +- .../CascadiaSettingsSerialization.cpp | 8 +- .../TerminalSettingsModel/Command.cpp | 2 +- .../TerminalSettingsModel/DefaultTerminal.cpp | 4 +- .../TerminalSettingsModel/DefaultTerminal.h | 2 +- .../WinRTUtils/inc/LibraryResources.h | 9 + src/cascadia/WinRTUtils/inc/WtExeUtils.h | 2 +- src/cascadia/WindowsTerminal/AppHost.cpp | 2 +- .../WindowsTerminal/WindowEmperor.cpp | 2 +- src/cascadia/inc/cppwinrt_utils.h | 2 +- src/inc/LibraryIncludes.h | 5 +- src/renderer/atlas/pch.h | 14 +- src/terminal/adapter/DispatchTypes.hpp | 30 +- src/terminal/adapter/adaptDispatch.cpp | 10 +- src/types/UiaTracing.cpp | 2 +- src/types/utils.cpp | 2 +- vcpkg.json | 4 +- 41 files changed, 275 insertions(+), 335 deletions(-) diff --git a/.github/actions/spelling/expect/expect.txt b/.github/actions/spelling/expect/expect.txt index 720fc383b0..fc5bb6d902 100644 --- a/.github/actions/spelling/expect/expect.txt +++ b/.github/actions/spelling/expect/expect.txt @@ -143,8 +143,8 @@ BTNFACE bufferout buffersize buflen -buildtransitive buildsystems +buildtransitive BValue bytebuffer cac @@ -2141,6 +2141,7 @@ XBUTTONDOWN XBUTTONUP XCast XCENTER +xchar xcopy XCount xdy diff --git a/src/cascadia/TerminalApp/AppActionHandlers.cpp b/src/cascadia/TerminalApp/AppActionHandlers.cpp index 1c362d18d9..bc2f5f4fff 100644 --- a/src/cascadia/TerminalApp/AppActionHandlers.cpp +++ b/src/cascadia/TerminalApp/AppActionHandlers.cpp @@ -910,10 +910,8 @@ namespace winrt::TerminalApp::implementation // Build the commandline to pass to wt for this set of NewTerminalArgs // `-w -1` will ensure a new window is created. - winrt::hstring cmdline{ - fmt::format(L"-w -1 new-tab {}", - terminalArgs.ToCommandline().c_str()) - }; + const auto commandline = terminalArgs.ToCommandline(); + winrt::hstring cmdline{ fmt::format(FMT_COMPILE(L"-w -1 new-tab {}"), commandline) }; // Build the args to ShellExecuteEx. We need to use ShellExecuteEx so we // can pass the SEE_MASK_NOASYNC flag. That flag allows us to safely @@ -1107,14 +1105,14 @@ namespace winrt::TerminalApp::implementation { if (const auto& realArgs = args.ActionArgs().try_as()) { - queryUrl = realArgs.QueryUrl().c_str(); + queryUrl = std::wstring_view{ realArgs.QueryUrl() }; } } // use global default if query URL is unspecified if (queryUrl.empty()) { - queryUrl = _settings.GlobalSettings().SearchWebDefaultQueryUrl().c_str(); + queryUrl = std::wstring_view{ _settings.GlobalSettings().SearchWebDefaultQueryUrl() }; } constexpr std::wstring_view queryToken{ L"%s" }; diff --git a/src/cascadia/TerminalApp/AppLogic.cpp b/src/cascadia/TerminalApp/AppLogic.cpp index dc11b50644..1a73c777c0 100644 --- a/src/cascadia/TerminalApp/AppLogic.cpp +++ b/src/cascadia/TerminalApp/AppLogic.cpp @@ -325,7 +325,7 @@ namespace winrt::TerminalApp::implementation // // So DON'T ~give a mouse a cookie~ take a static ref here. - const winrt::hstring modifiedBasename{ std::filesystem::path{ fileModified }.filename().c_str() }; + const auto modifiedBasename = std::filesystem::path{ fileModified }.filename(); if (modifiedBasename == settingsBasename) { diff --git a/src/cascadia/TerminalApp/CommandPalette.cpp b/src/cascadia/TerminalApp/CommandPalette.cpp index 2e6338234e..b54ee9a5c6 100644 --- a/src/cascadia/TerminalApp/CommandPalette.cpp +++ b/src/cascadia/TerminalApp/CommandPalette.cpp @@ -626,7 +626,7 @@ namespace winrt::TerminalApp::implementation automationPeer.RaiseNotificationEvent( Automation::Peers::AutomationNotificationKind::ActionCompleted, Automation::Peers::AutomationNotificationProcessing::CurrentThenMostRecent, - fmt::format(std::wstring_view{ RS_(L"CommandPalette_NestedCommandAnnouncement") }, ParentCommandName()), + RS_fmt(L"CommandPalette_NestedCommandAnnouncement", ParentCommandName()), L"CommandPaletteNestingLevelChanged" /* unique name for this notification category */); } } @@ -879,7 +879,7 @@ namespace winrt::TerminalApp::implementation Automation::Peers::AutomationNotificationKind::ActionCompleted, Automation::Peers::AutomationNotificationProcessing::ImportantMostRecent, currentNeedleHasResults ? - winrt::hstring{ fmt::format(std::wstring_view{ RS_(L"CommandPalette_MatchesAvailable") }, _filteredActions.Size()) } : + winrt::hstring{ RS_fmt(L"CommandPalette_MatchesAvailable", _filteredActions.Size()) } : NoMatchesText(), // what to announce if results were found L"CommandPaletteResultAnnouncement" /* unique name for this group of notifications */); } diff --git a/src/cascadia/TerminalApp/Jumplist.cpp b/src/cascadia/TerminalApp/Jumplist.cpp index 050fdbb429..5f3e3f12f7 100644 --- a/src/cascadia/TerminalApp/Jumplist.cpp +++ b/src/cascadia/TerminalApp/Jumplist.cpp @@ -121,7 +121,7 @@ void Jumplist::_updateProfiles(IObjectCollection* jumplistItems, winrt::Windows: for (const auto& profile : profiles) { // Craft the arguments following "wt.exe" - auto args = fmt::format(L"-p {}", to_hstring(profile.Guid())); + auto args = fmt::format(FMT_COMPILE(L"-p {}"), to_hstring(profile.Guid())); // Create the shell link object for the profile const auto normalizedIconPath{ _normalizeIconPath(profile.Icon()) }; diff --git a/src/cascadia/TerminalApp/SnippetsPaneContent.h b/src/cascadia/TerminalApp/SnippetsPaneContent.h index 19f8555982..b394f94b4e 100644 --- a/src/cascadia/TerminalApp/SnippetsPaneContent.h +++ b/src/cascadia/TerminalApp/SnippetsPaneContent.h @@ -97,7 +97,7 @@ namespace winrt::TerminalApp::implementation { if (const auto& sendInput{ command.ActionAndArgs().Args().try_as() }) { - return winrt::hstring{ til::visualize_nonspace_control_codes(sendInput.Input().c_str()) }; + return winrt::hstring{ til::visualize_nonspace_control_codes(std::wstring{ sendInput.Input() }) }; } } } diff --git a/src/cascadia/TerminalApp/SuggestionsControl.cpp b/src/cascadia/TerminalApp/SuggestionsControl.cpp index 366205fc85..e6f482ac19 100644 --- a/src/cascadia/TerminalApp/SuggestionsControl.cpp +++ b/src/cascadia/TerminalApp/SuggestionsControl.cpp @@ -654,7 +654,7 @@ namespace winrt::TerminalApp::implementation automationPeer.RaiseNotificationEvent( Automation::Peers::AutomationNotificationKind::ActionCompleted, Automation::Peers::AutomationNotificationProcessing::CurrentThenMostRecent, - fmt::format(std::wstring_view{ RS_(L"SuggestionsControl_NestedCommandAnnouncement") }, ParentCommandName()), + RS_fmt(L"SuggestionsControl_NestedCommandAnnouncement", ParentCommandName()), L"SuggestionsControlNestingLevelChanged" /* unique name for this notification category */); } } @@ -810,7 +810,7 @@ namespace winrt::TerminalApp::implementation Automation::Peers::AutomationNotificationKind::ActionCompleted, Automation::Peers::AutomationNotificationProcessing::ImportantMostRecent, currentNeedleHasResults ? - winrt::hstring{ fmt::format(std::wstring_view{ RS_(L"SuggestionsControl_MatchesAvailable") }, _filteredActions.Size()) } : + winrt::hstring{ RS_fmt(L"SuggestionsControl_MatchesAvailable", _filteredActions.Size()) } : NoMatchesText(), // what to announce if results were found L"SuggestionsControlResultAnnouncement" /* unique name for this group of notifications */); } diff --git a/src/cascadia/TerminalApp/TabManagement.cpp b/src/cascadia/TerminalApp/TabManagement.cpp index 79d830dca1..2348e70f73 100644 --- a/src/cascadia/TerminalApp/TabManagement.cpp +++ b/src/cascadia/TerminalApp/TabManagement.cpp @@ -1035,7 +1035,7 @@ namespace winrt::TerminalApp::implementation const auto tabTitle = tab.Title(); autoPeer.RaiseNotificationEvent(Automation::Peers::AutomationNotificationKind::ActionCompleted, Automation::Peers::AutomationNotificationProcessing::ImportantMostRecent, - fmt::format(std::wstring_view{ RS_(L"TerminalPage_TabMovedAnnouncement_Direction") }, tabTitle, newTabIndex + 1), + RS_fmt(L"TerminalPage_TabMovedAnnouncement_Direction", tabTitle, newTabIndex + 1), L"TerminalPageMoveTabWithDirection" /* unique name for this notification category */); } } diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp index b03b7e3721..002886fd3b 100644 --- a/src/cascadia/TerminalApp/TerminalPage.cpp +++ b/src/cascadia/TerminalApp/TerminalPage.cpp @@ -2148,7 +2148,7 @@ namespace winrt::TerminalApp::implementation { autoPeer.RaiseNotificationEvent(Automation::Peers::AutomationNotificationKind::ActionCompleted, Automation::Peers::AutomationNotificationProcessing::ImportantMostRecent, - fmt::format(std::wstring_view{ RS_(L"TerminalPage_PaneMovedAnnouncement_ExistingWindow2") }, windowId), + RS_fmt(L"TerminalPage_PaneMovedAnnouncement_ExistingWindow2", windowId), L"TerminalPageMovePaneToExistingWindow" /* unique name for this notification category */); } } @@ -2183,7 +2183,7 @@ namespace winrt::TerminalApp::implementation const auto tabTitle = targetTab->Title(); autoPeer.RaiseNotificationEvent(Automation::Peers::AutomationNotificationKind::ActionCompleted, Automation::Peers::AutomationNotificationProcessing::ImportantMostRecent, - fmt::format(std::wstring_view{ RS_(L"TerminalPage_PaneMovedAnnouncement_ExistingTab") }, tabTitle), + RS_fmt(L"TerminalPage_PaneMovedAnnouncement_ExistingTab", tabTitle), L"TerminalPageMovePaneToExistingTab" /* unique name for this notification category */); } } @@ -2283,14 +2283,14 @@ namespace winrt::TerminalApp::implementation { autoPeer.RaiseNotificationEvent(Automation::Peers::AutomationNotificationKind::ActionCompleted, Automation::Peers::AutomationNotificationProcessing::ImportantMostRecent, - fmt::format(std::wstring_view{ RS_(L"TerminalPage_TabMovedAnnouncement_NewWindow") }, tabTitle), + RS_fmt(L"TerminalPage_TabMovedAnnouncement_NewWindow", tabTitle), L"TerminalPageMoveTabToNewWindow" /* unique name for this notification category */); } else { autoPeer.RaiseNotificationEvent(Automation::Peers::AutomationNotificationKind::ActionCompleted, Automation::Peers::AutomationNotificationProcessing::ImportantMostRecent, - fmt::format(std::wstring_view{ RS_(L"TerminalPage_TabMovedAnnouncement_Default") }, tabTitle, windowId), + RS_fmt(L"TerminalPage_TabMovedAnnouncement_Default", tabTitle, windowId), L"TerminalPageMoveTabToExistingWindow" /* unique name for this notification category */); } } @@ -2831,7 +2831,7 @@ namespace winrt::TerminalApp::implementation { try { - auto parsed = winrt::Windows::Foundation::Uri(eventArgs.Uri().c_str()); + auto parsed = winrt::Windows::Foundation::Uri(eventArgs.Uri()); if (_IsUriSupported(parsed)) { ShellExecute(nullptr, L"open", eventArgs.Uri().c_str(), nullptr, nullptr, SW_SHOWNORMAL); @@ -4176,8 +4176,8 @@ namespace winrt::TerminalApp::implementation winrt::hstring TerminalPage::KeyboardServiceDisabledText() { const auto serviceName{ _getTabletServiceName() }; - const winrt::hstring text{ fmt::format(std::wstring_view(RS_(L"KeyboardServiceWarningText")), serviceName) }; - return text; + const auto text{ RS_fmt(L"KeyboardServiceWarningText", serviceName) }; + return winrt::hstring{ text }; } // Method Description: @@ -4467,7 +4467,7 @@ namespace winrt::TerminalApp::implementation // Build the commandline to pass to wt for this set of NewTerminalArgs auto cmdline{ - fmt::format(L"new-tab {}", newTerminalArgs.ToCommandline().c_str()) + fmt::format(FMT_COMPILE(L"new-tab {}"), newTerminalArgs.ToCommandline()) }; wil::unique_process_information pi; @@ -5221,7 +5221,7 @@ namespace winrt::TerminalApp::implementation { // `this` is safe to use in here. - _sendDraggedTabToWindow(winrt::hstring{ fmt::format(L"{}", args.TargetWindow()) }, + _sendDraggedTabToWindow(winrt::to_hstring(args.TargetWindow()), args.TabIndex(), std::nullopt); } diff --git a/src/cascadia/TerminalApp/TerminalTab.cpp b/src/cascadia/TerminalApp/TerminalTab.cpp index 961df655dd..566e6b6fbd 100644 --- a/src/cascadia/TerminalApp/TerminalTab.cpp +++ b/src/cascadia/TerminalApp/TerminalTab.cpp @@ -1873,7 +1873,7 @@ namespace winrt::TerminalApp::implementation const auto profileName{ control.Settings().ProfileName() }; if (profileName != Title()) { - return fmt::format(L"{}: {}", profileName, Title()).data(); + return winrt::hstring{ fmt::format(FMT_COMPILE(L"{}: {}"), profileName, Title()) }; } } diff --git a/src/cascadia/TerminalApp/TerminalWindow.cpp b/src/cascadia/TerminalApp/TerminalWindow.cpp index c04a34affc..539aa01e93 100644 --- a/src/cascadia/TerminalApp/TerminalWindow.cpp +++ b/src/cascadia/TerminalApp/TerminalWindow.cpp @@ -1362,7 +1362,7 @@ namespace winrt::TerminalApp::implementation // - a string for displaying the name of the window. winrt::hstring WindowProperties::WindowIdForDisplay() const noexcept { - return winrt::hstring{ fmt::format(L"{}: {}", + return winrt::hstring{ fmt::format(FMT_COMPILE(L"{}: {}"), std::wstring_view(RS_(L"WindowIdLabel")), _WindowId) }; } @@ -1376,7 +1376,7 @@ namespace winrt::TerminalApp::implementation winrt::hstring WindowProperties::WindowNameForDisplay() const noexcept { return _WindowName.empty() ? - winrt::hstring{ fmt::format(L"<{}>", RS_(L"UnnamedWindowName")) } : + winrt::hstring{ fmt::format(FMT_COMPILE(L"<{}>"), RS_(L"UnnamedWindowName")) } : _WindowName; } diff --git a/src/cascadia/TerminalConnection/AzureConnection.cpp b/src/cascadia/TerminalConnection/AzureConnection.cpp index e633e9b80c..210f7cc06c 100644 --- a/src/cascadia/TerminalConnection/AzureConnection.cpp +++ b/src/cascadia/TerminalConnection/AzureConnection.cpp @@ -37,7 +37,7 @@ static constexpr winrt::guid AzureConnectionType = { 0xd9fcfdfa, 0xa479, 0x412c, static inline std::wstring _colorize(const unsigned int colorCode, const std::wstring_view text) { - return fmt::format(L"\x1b[{0}m{1}\x1b[m", colorCode, text); + return fmt::format(FMT_COMPILE(L"\x1b[{0}m{1}\x1b[m"), colorCode, text); } // Takes N resource names, loads the first one as a format string, and then @@ -47,15 +47,18 @@ static inline std::wstring _colorize(const unsigned int colorCode, const std::ws template static inline std::wstring _formatResWithColoredUserInputOptions(const std::wstring_view resourceKey, Args&&... args) { - return fmt::format(std::wstring_view{ GetLibraryResourceString(resourceKey) }, (_colorize(USER_INPUT_COLOR, GetLibraryResourceString(args)))...); + const auto format = GetLibraryResourceString(resourceKey); + return fmt::format(fmt::runtime(std::wstring_view{ format }), (_colorize(USER_INPUT_COLOR, GetLibraryResourceString(args)))...); } static inline std::wstring _formatTenant(int tenantNumber, const Tenant& tenant) { - return fmt::format(std::wstring_view{ RS_(L"AzureIthTenant") }, - _colorize(USER_INPUT_COLOR, std::to_wstring(tenantNumber)), - _colorize(USER_INFO_COLOR, tenant.DisplayName.value_or(std::wstring{ RS_(L"AzureUnknownTenantName") })), - tenant.DefaultDomain.value_or(tenant.ID)); // use the domain name if possible, ID if not. + return RS_fmt( + L"AzureIthTenant", + _colorize(USER_INPUT_COLOR, std::to_wstring(tenantNumber)), + _colorize(USER_INFO_COLOR, tenant.DisplayName.value_or(std::wstring{ RS_(L"AzureUnknownTenantName") })), + tenant.DefaultDomain.value_or(tenant.ID) // use the domain name if possible, ID if not. + ); } namespace winrt::Microsoft::Terminal::TerminalConnection::implementation @@ -244,7 +247,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation } else // We only transition to Connected when we've established the websocket. { - auto uri{ fmt::format(L"{}terminals/{}/size?cols={}&rows={}&version=2019-01-01", _cloudShellUri, _terminalID, columns, rows) }; + auto uri{ fmt::format(FMT_COMPILE(L"{}terminals/{}/size?cols={}&rows={}&version=2019-01-01"), _cloudShellUri, _terminalID, columns, rows) }; WWH::HttpStringContent content{ L"", @@ -851,7 +854,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation // - the response to the device code flow initiation WDJ::JsonObject AzureConnection::_GetDeviceCode() { - auto uri{ fmt::format(L"{}common/oauth2/devicecode", _loginUri) }; + auto uri{ fmt::format(FMT_COMPILE(L"{}common/oauth2/devicecode"), _loginUri) }; WWH::HttpFormUrlEncodedContent content{ std::unordered_map{ { winrt::hstring{ L"client_id" }, winrt::hstring{ AzureClientID } }, @@ -872,7 +875,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation // - else, throw an exception WDJ::JsonObject AzureConnection::_WaitForUser(const winrt::hstring& deviceCode, int pollInterval, int expiresIn) { - auto uri{ fmt::format(L"{}common/oauth2/token", _loginUri) }; + auto uri{ fmt::format(FMT_COMPILE(L"{}common/oauth2/token"), _loginUri) }; WWH::HttpFormUrlEncodedContent content{ std::unordered_map{ { winrt::hstring{ L"grant_type" }, winrt::hstring{ L"device_code" } }, @@ -923,7 +926,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation // - the response which contains a list of the user's Azure tenants void AzureConnection::_PopulateTenantList() { - auto uri{ fmt::format(L"{}tenants?api-version=2020-01-01", _resourceUri) }; + auto uri{ fmt::format(FMT_COMPILE(L"{}tenants?api-version=2020-01-01"), _resourceUri) }; // Send the request and return the response as a json value auto tenantResponse{ _SendRequestReturningJson(uri, nullptr) }; @@ -939,7 +942,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation // - the response with the new tokens void AzureConnection::_RefreshTokens() { - auto uri{ fmt::format(L"{}{}/oauth2/token", _loginUri, _currentTenant->ID) }; + auto uri{ fmt::format(FMT_COMPILE(L"{}{}/oauth2/token"), _loginUri, _currentTenant->ID) }; WWH::HttpFormUrlEncodedContent content{ std::unordered_map{ { winrt::hstring{ L"grant_type" }, winrt::hstring{ L"refresh_token" } }, @@ -962,7 +965,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation // - the user's cloud shell settings WDJ::JsonObject AzureConnection::_GetCloudShellUserSettings() { - auto uri{ fmt::format(L"{}providers/Microsoft.Portal/userSettings/cloudconsole?api-version=2023-02-01-preview", _resourceUri) }; + auto uri{ fmt::format(FMT_COMPILE(L"{}providers/Microsoft.Portal/userSettings/cloudconsole?api-version=2023-02-01-preview"), _resourceUri) }; return _SendRequestReturningJson(uri, nullptr); } @@ -972,7 +975,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation // - the uri for the cloud shell winrt::hstring AzureConnection::_GetCloudShell() { - auto uri{ fmt::format(L"{}providers/Microsoft.Portal/consoles/default?api-version=2023-02-01-preview", _resourceUri) }; + auto uri{ fmt::format(FMT_COMPILE(L"{}providers/Microsoft.Portal/consoles/default?api-version=2023-02-01-preview"), _resourceUri) }; WWH::HttpStringContent content{ LR"-({"properties": {"osType": "linux"}})-", @@ -992,7 +995,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation // - the uri for the terminal winrt::hstring AzureConnection::_GetTerminal(const winrt::hstring& shellType) { - auto uri{ fmt::format(L"{}terminals?cols={}&rows={}&version=2019-01-01&shell={}", _cloudShellUri, _initialCols, _initialRows, shellType) }; + auto uri{ fmt::format(FMT_COMPILE(L"{}terminals?cols={}&rows={}&version=2019-01-01&shell={}"), _cloudShellUri, _initialCols, _initialRows, shellType) }; WWH::HttpStringContent content{ L"{}", diff --git a/src/cascadia/TerminalConnection/ConptyConnection.cpp b/src/cascadia/TerminalConnection/ConptyConnection.cpp index 5b8cb22028..23a7e263b8 100644 --- a/src/cascadia/TerminalConnection/ConptyConnection.cpp +++ b/src/cascadia/TerminalConnection/ConptyConnection.cpp @@ -14,10 +14,6 @@ #include "ConptyConnection.g.cpp" using namespace ::Microsoft::Console; -using namespace std::string_view_literals; - -// Format is: "DecimalResult (HexadecimalForm)" -static constexpr auto _errorFormat = L"{0} ({0:#010x})"sv; // Notes: // There is a number of ways that the Conpty connection can be terminated (voluntarily or not): @@ -77,7 +73,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation std::set keys{}; for (const auto item : _environment) { - keys.insert(item.Key().c_str()); + keys.insert(std::wstring{ item.Key() }); } // add additional env vars for (const auto& key : keys) @@ -422,16 +418,13 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation const auto hr = wil::ResultFromCaughtException(); // GH#11556 - make sure to format the error code to this string as an UNSIGNED int - winrt::hstring failureText{ fmt::format(std::wstring_view{ RS_(L"ProcessFailedToLaunch") }, - fmt::format(_errorFormat, static_cast(hr)), - _commandline) }; + const 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 (hr == HRESULT_FROM_WIN32(ERROR_DIRECTORY)) { - winrt::hstring badPathText{ fmt::format(std::wstring_view{ RS_(L"BadPathText") }, - _startingDirectory) }; + const auto badPathText = RS_fmt(L"BadPathText", _startingDirectory); TerminalOutput.raise(L"\r\n"); TerminalOutput.raise(badPathText); } @@ -451,7 +444,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation try { // GH#11556 - make sure to format the error code to this string as an UNSIGNED int - const auto msg1 = fmt::format(std::wstring_view{ RS_(L"ProcessExited") }, fmt::format(_errorFormat, status)); + const auto msg1 = RS_fmt(L"ProcessExited", _formatStatus(status)); const auto msg2 = RS_(L"CtrlDToClose"); const auto msg = fmt::format(FMT_COMPILE(L"\r\n{}\r\n{}\r\n"), msg1, msg2); TerminalOutput.raise(msg); @@ -459,6 +452,11 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation CATCH_LOG(); } + std::wstring ConptyConnection::_formatStatus(uint32_t status) + { + return fmt::format(FMT_COMPILE(L"{0} ({0:#010x})"), status); + } + // Method Description: // - called when the client application (not necessarily its pty) exits for any reason void ConptyConnection::_LastConPtyClientDisconnected() noexcept diff --git a/src/cascadia/TerminalConnection/ConptyConnection.h b/src/cascadia/TerminalConnection/ConptyConnection.h index 6fd476b0cb..85f292baad 100644 --- a/src/cascadia/TerminalConnection/ConptyConnection.h +++ b/src/cascadia/TerminalConnection/ConptyConnection.h @@ -60,6 +60,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation HRESULT _LaunchAttachedClient() noexcept; void _indicateExitWithStatus(unsigned int status) noexcept; + static std::wstring _formatStatus(uint32_t status); void _LastConPtyClientDisconnected() noexcept; til::CoordType _rows = 120; diff --git a/src/cascadia/TerminalControl/SearchBoxControl.cpp b/src/cascadia/TerminalControl/SearchBoxControl.cpp index 0a63da28c0..7cedfb6699 100644 --- a/src/cascadia/TerminalControl/SearchBoxControl.cpp +++ b/src/cascadia/TerminalControl/SearchBoxControl.cpp @@ -487,7 +487,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation } else { - currentString = fmt::format(L"{}", currentMatch + 1); + currentString = fmt::to_wstring(currentMatch + 1); } if (totalMatches > MaximumTotalResultsToShowInStatus) @@ -496,10 +496,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation } else { - totalString = fmt::format(L"{}", totalMatches); + totalString = fmt::to_wstring(totalMatches); } - return winrt::hstring{ fmt::format(RS_(L"TermControl_NumResults").c_str(), currentString, totalString) }; + return winrt::hstring{ RS_fmt(L"TermControl_NumResults", currentString, totalString) }; } // Method Description: diff --git a/src/cascadia/TerminalControl/TermControl.cpp b/src/cascadia/TerminalControl/TermControl.cpp index 01184981d4..045762a3ac 100644 --- a/src/cascadia/TerminalControl/TermControl.cpp +++ b/src/cascadia/TerminalControl/TermControl.cpp @@ -1203,13 +1203,13 @@ namespace winrt::Microsoft::Terminal::Control::implementation { case HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND): case HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND): - message = winrt::hstring{ fmt::format(std::wstring_view{ RS_(L"PixelShaderNotFound") }, parameter) }; + message = RS_fmt(L"PixelShaderNotFound", parameter); break; case D2DERR_SHADER_COMPILE_FAILED: - message = winrt::hstring{ fmt::format(std::wstring_view{ RS_(L"PixelShaderCompileFailed") }, parameter) }; + message = RS_fmt(L"PixelShaderCompileFailed", parameter); break; case DWRITE_E_NOFONT: - message = winrt::hstring{ fmt::format(std::wstring_view{ RS_(L"RendererErrorFontNotFound") }, parameter) }; + message = RS_fmt(L"RendererErrorFontNotFound", parameter); break; case ATLAS_ENGINE_ERROR_MAC_TYPE: message = RS_(L"RendererErrorMacType"); @@ -1219,9 +1219,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation wchar_t buf[512]; const auto len = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, nullptr, hr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), &buf[0], ARRAYSIZE(buf), nullptr); const std::wstring_view msg{ &buf[0], len }; - std::wstring resourceString = RS_(L"RendererErrorOther").c_str(); //conditional message construction - std::wstring partialMessage = fmt::format(std::wstring_view{ resourceString }, hr, msg); + auto partialMessage = RS_fmt(L"RendererErrorOther", hr, msg); if (!parameter.empty()) { fmt::format_to(std::back_inserter(partialMessage), LR"( "{0}")", parameter); @@ -3854,7 +3853,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation automationPeer.RaiseNotificationEvent( AutomationNotificationKind::ItemAdded, AutomationNotificationProcessing::All, - winrt::hstring{ fmt::format(std::wstring_view{ RS_(L"PreviewTextAnnouncement") }, text) }, + RS_fmt(L"PreviewTextAnnouncement", text), L"PreviewTextAnnouncement" /* unique name for this group of notifications */); } } diff --git a/src/cascadia/TerminalSettingsEditor/ColorSchemeViewModel.cpp b/src/cascadia/TerminalSettingsEditor/ColorSchemeViewModel.cpp index fc6a4bc5af..fef533a8f5 100644 --- a/src/cascadia/TerminalSettingsEditor/ColorSchemeViewModel.cpp +++ b/src/cascadia/TerminalSettingsEditor/ColorSchemeViewModel.cpp @@ -57,7 +57,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation { if (IsDefaultScheme()) { - return hstring{ fmt::format(L"{0} ({1})", Name(), RS_(L"ColorScheme_DefaultTag/Text")) }; + return hstring{ fmt::format(FMT_COMPILE(L"{} ({})"), Name(), RS_(L"ColorScheme_DefaultTag/Text")) }; } return Name(); } diff --git a/src/cascadia/TerminalSettingsEditor/ColorSchemesPageViewModel.cpp b/src/cascadia/TerminalSettingsEditor/ColorSchemesPageViewModel.cpp index a4d17dbb3e..db30847db1 100644 --- a/src/cascadia/TerminalSettingsEditor/ColorSchemesPageViewModel.cpp +++ b/src/cascadia/TerminalSettingsEditor/ColorSchemesPageViewModel.cpp @@ -97,7 +97,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation Editor::ColorSchemeViewModel ColorSchemesPageViewModel::RequestAddNew() { - const hstring schemeName{ fmt::format(L"Color Scheme {}", _settings.GlobalSettings().ColorSchemes().Size() + 1) }; + const auto schemeName{ fmt::format(FMT_COMPILE(L"Color Scheme {}"), _settings.GlobalSettings().ColorSchemes().Size() + 1) }; Model::ColorScheme scheme{ schemeName }; // Add the new color scheme diff --git a/src/cascadia/TerminalSettingsEditor/LaunchViewModel.cpp b/src/cascadia/TerminalSettingsEditor/LaunchViewModel.cpp index 425d84299b..dcaaff6e3e 100644 --- a/src/cascadia/TerminalSettingsEditor/LaunchViewModel.cpp +++ b/src/cascadia/TerminalSettingsEditor/LaunchViewModel.cpp @@ -49,17 +49,17 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation // Append the launch position part if (UseDefaultLaunchPosition()) { - result = fmt::format(L"{}, {}", launchModeString, RS_(L"Globals_DefaultLaunchPositionCheckbox/Content")); + result = fmt::format(FMT_COMPILE(L"{}, {}"), launchModeString, RS_(L"Globals_DefaultLaunchPositionCheckbox/Content")); } else { - const std::wstring xPosString = isnan(InitialPosX()) ? RS_(L"Globals_LaunchModeDefault/Content").c_str() : std::to_wstring(gsl::narrow_cast(InitialPosX())); - const std::wstring yPosString = isnan(InitialPosY()) ? RS_(L"Globals_LaunchModeDefault/Content").c_str() : std::to_wstring(gsl::narrow_cast(InitialPosY())); - result = fmt::format(L"{}, ({},{})", launchModeString, xPosString, yPosString); + const auto xPosString = isnan(InitialPosX()) ? RS_(L"Globals_LaunchModeDefault/Content") : winrt::to_hstring(gsl::narrow_cast(InitialPosX())); + const auto yPosString = isnan(InitialPosY()) ? RS_(L"Globals_LaunchModeDefault/Content") : winrt::to_hstring(gsl::narrow_cast(InitialPosY())); + result = fmt::format(FMT_COMPILE(L"{}, ({},{})"), launchModeString, xPosString, yPosString); } // Append the CenterOnLaunch part - result = CenterOnLaunch() ? winrt::hstring{ fmt::format(L"{}, {}", result, RS_(L"Globals_CenterOnLaunchCentered")) } : result; + result = CenterOnLaunch() ? winrt::hstring{ fmt::format(FMT_COMPILE(L"{}, {}"), result, RS_(L"Globals_CenterOnLaunchCentered")) } : result; return result; } diff --git a/src/cascadia/TerminalSettingsEditor/SettingContainer.cpp b/src/cascadia/TerminalSettingsEditor/SettingContainer.cpp index 825e79c18e..8a32fbacb3 100644 --- a/src/cascadia/TerminalSettingsEditor/SettingContainer.cpp +++ b/src/cascadia/TerminalSettingsEditor/SettingContainer.cpp @@ -255,7 +255,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation if (originTag == Model::OriginTag::Fragment || originTag == Model::OriginTag::Generated) { // from a fragment extension or generated profile - return hstring{ fmt::format(std::wstring_view{ RS_(L"SettingContainer_OverrideMessageFragmentExtension") }, source) }; + return hstring{ RS_fmt(L"SettingContainer_OverrideMessageFragmentExtension", source) }; } return RS_(L"SettingContainer_OverrideMessageBaseLayer"); } diff --git a/src/cascadia/TerminalSettingsModel/ActionAndArgs.cpp b/src/cascadia/TerminalSettingsModel/ActionAndArgs.cpp index 23e5d59a35..5d2bd48626 100644 --- a/src/cascadia/TerminalSettingsModel/ActionAndArgs.cpp +++ b/src/cascadia/TerminalSettingsModel/ActionAndArgs.cpp @@ -8,6 +8,7 @@ #include "HashUtils.h" #include +#include static constexpr std::string_view AdjustFontSizeKey{ "adjustFontSize" }; static constexpr std::string_view CloseOtherPanesKey{ "closeOtherPanes" }; @@ -105,52 +106,48 @@ static constexpr std::string_view ActionKey{ "action" }; // This key is reserved to remove a keybinding, instead of mapping it to an action. static constexpr std::string_view UnboundKey{ "unbound" }; -#define KEY_TO_ACTION_PAIR(action) { action##Key, ShortcutAction::action }, -#define ACTION_TO_KEY_PAIR(action) { ShortcutAction::action, action##Key }, -#define ACTION_TO_SERIALIZERS_PAIR(action) { ShortcutAction::action, { action##Args::FromJson, action##Args::ToJson } }, - namespace winrt::Microsoft::Terminal::Settings::Model::implementation { using namespace ::Microsoft::Terminal::Settings::Model; - // Specifically use a map here over an unordered_map. We want to be able to - // iterate over these entries in-order when we're serializing the keybindings. - // HERE BE DRAGONS: - // These are string_views that are being used as keys. These string_views are - // just pointers to other strings. This could be dangerous, if the map outlived - // the actual strings being pointed to. However, since both these strings and - // the map are all const for the lifetime of the app, we have nothing to worry - // about here. - const std::map> ActionAndArgs::ActionKeyNamesMap{ + using ParseActionFunction = FromJsonResult (*)(const Json::Value&); + using SerializeActionFunction = Json::Value (*)(const IActionArgs&); + + using KeyToActionPair = std::pair; + using ActionToKeyPair = std::pair; + using SerializersPair = std::pair; + using ActionToSerializersPair = std::pair; + +#define KEY_TO_ACTION_PAIR(action) KeyToActionPair{ action##Key, ShortcutAction::action }, +#define ACTION_TO_KEY_PAIR(action) ActionToKeyPair{ ShortcutAction::action, action##Key }, +#define ACTION_TO_SERIALIZERS_PAIR(action) ActionToSerializersPair{ ShortcutAction::action, { action##Args::FromJson, action##Args::ToJson } }, + + static constexpr til::static_map ActionKeyNamesMap{ #define ON_ALL_ACTIONS(action) KEY_TO_ACTION_PAIR(action) ALL_SHORTCUT_ACTIONS // Don't include the INTERNAL_SHORTCUT_ACTIONS here #undef ON_ALL_ACTIONS }; - static const std::map> ActionToStringMap{ + static constexpr til::static_map ActionToStringMap{ #define ON_ALL_ACTIONS(action) ACTION_TO_KEY_PAIR(action) ALL_SHORTCUT_ACTIONS // Don't include the INTERNAL_SHORTCUT_ACTIONS here #undef ON_ALL_ACTIONS }; - using ParseResult = std::tuple>; - using ParseActionFunction = std::function; - using SerializeActionFunction = std::function; - // This is a map of ShortcutAction->{function, function. It holds // a set of (de)serializer functions that can be used to (de)serialize an IActionArgs // from json. Each type of IActionArgs that can accept arbitrary args should be // placed into this map, with the corresponding deserializer function as the // value. - static const std::unordered_map> argSerializerMap{ + static constexpr til::static_map argSerializerMap{ // These are special cases. // - QuakeMode: deserializes into a GlobalSummon, so we don't need a serializer // - Invalid: has no args - { ShortcutAction::QuakeMode, { GlobalSummonArgs::QuakeModeFromJson, nullptr } }, - { ShortcutAction::Invalid, { nullptr, nullptr } }, + ActionToSerializersPair{ ShortcutAction::QuakeMode, { &GlobalSummonArgs::QuakeModeFromJson, nullptr } }, + ActionToSerializersPair{ ShortcutAction::Invalid, { nullptr, nullptr } }, #define ON_ALL_ACTIONS_WITH_ARGS(action) ACTION_TO_SERIALIZERS_PAIR(action) ALL_SHORTCUT_ACTIONS_WITH_ARGS @@ -198,8 +195,8 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation { // Try matching the command to one we have. If we can't find the // action name in our list of names, let's just unbind that key. - const auto found = ActionAndArgs::ActionKeyNamesMap.find(actionString); - return found != ActionAndArgs::ActionKeyNamesMap.end() ? found->second : ShortcutAction::Invalid; + const auto found = ActionKeyNamesMap.find(actionString); + return found != ActionKeyNamesMap.end() ? found->second : ShortcutAction::Invalid; } // Method Description: @@ -468,7 +465,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation if (_Action != ShortcutAction::Invalid) { auto actionKeyString = ActionToStringMap.find(_Action)->second; - auto result = fmt::format(FMT_COMPILE(L"User.{}"), actionKeyString); + auto result = fmt::format(FMT_COMPILE(L"User.{}"), winrt::to_hstring(actionKeyString)); if (_Args) { // If there are args, we need to append the hash of the args diff --git a/src/cascadia/TerminalSettingsModel/ActionAndArgs.h b/src/cascadia/TerminalSettingsModel/ActionAndArgs.h index 9c841ca727..cc62ee6731 100644 --- a/src/cascadia/TerminalSettingsModel/ActionAndArgs.h +++ b/src/cascadia/TerminalSettingsModel/ActionAndArgs.h @@ -11,7 +11,6 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation { struct ActionAndArgs : public ActionAndArgsT { - static const std::map> ActionKeyNamesMap; static winrt::com_ptr FromJson(const Json::Value& json, std::vector& warnings); static Json::Value ToJson(const Model::ActionAndArgs& val); diff --git a/src/cascadia/TerminalSettingsModel/ActionArgs.cpp b/src/cascadia/TerminalSettingsModel/ActionArgs.cpp index 00c8861f0d..8b3e58a11b 100644 --- a/src/cascadia/TerminalSettingsModel/ActionArgs.cpp +++ b/src/cascadia/TerminalSettingsModel/ActionArgs.cpp @@ -60,82 +60,82 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation { winrt::hstring NewTerminalArgs::GenerateName() const { - std::wstringstream ss; + std::wstring str; if (!Profile().empty()) { - ss << fmt::format(L"profile: {}, ", Profile()); + fmt::format_to(std::back_inserter(str), FMT_COMPILE(L"profile: {}, "), Profile()); } else if (ProfileIndex()) { - ss << fmt::format(L"profile index: {}, ", ProfileIndex().Value()); + fmt::format_to(std::back_inserter(str), FMT_COMPILE(L"profile index: {}, "), ProfileIndex().Value()); } if (!Commandline().empty()) { - ss << fmt::format(L"commandline: {}, ", Commandline()); + fmt::format_to(std::back_inserter(str), FMT_COMPILE(L"commandline: {}, "), Commandline()); } if (!StartingDirectory().empty()) { - ss << fmt::format(L"directory: {}, ", StartingDirectory()); + fmt::format_to(std::back_inserter(str), FMT_COMPILE(L"directory: {}, "), StartingDirectory()); } if (!TabTitle().empty()) { - ss << fmt::format(L"title: {}, ", TabTitle()); + fmt::format_to(std::back_inserter(str), FMT_COMPILE(L"title: {}, "), TabTitle()); } if (TabColor()) { const til::color tabColor{ TabColor().Value() }; - ss << fmt::format(L"tabColor: {}, ", tabColor.ToHexString(true)); + fmt::format_to(std::back_inserter(str), FMT_COMPILE(L"tabColor: {}, "), tabColor.ToHexString(true)); } if (!ColorScheme().empty()) { - ss << fmt::format(L"colorScheme: {}, ", ColorScheme()); + fmt::format_to(std::back_inserter(str), FMT_COMPILE(L"colorScheme: {}, "), ColorScheme()); } if (SuppressApplicationTitle()) { if (SuppressApplicationTitle().Value()) { - ss << fmt::format(L"suppress application title, "); + str.append(L"suppress application title, "); } else { - ss << fmt::format(L"use application title, "); + str.append(L"use application title, "); } } if (Elevate()) { - ss << fmt::format(L"elevate: {}, ", Elevate().Value()); + fmt::format_to(std::back_inserter(str), FMT_COMPILE(L"elevate: {}, "), Elevate().Value()); } - auto s = ss.str(); - if (s.empty()) + if (str.empty()) { return {}; } // Chop off the last ", " - return winrt::hstring{ s.substr(0, s.size() - 2) }; + str.resize(str.size() - 2); + return winrt::hstring{ str }; } winrt::hstring NewTerminalArgs::ToCommandline() const { - std::wstringstream ss; + std::wstring str; if (!Profile().empty()) { - ss << fmt::format(L"--profile \"{}\" ", Profile()); + fmt::format_to(std::back_inserter(str), FMT_COMPILE(L"--profile \"{}\" "), Profile()); } if (const auto id = SessionId(); id != winrt::guid{}) { - const auto str = ::Microsoft::Console::Utils::GuidToString(id); - ss << fmt::format(L"--sessionId \"{}\" ", str); + const auto idStr = ::Microsoft::Console::Utils::GuidToString(id); + fmt::format_to(std::back_inserter(str), FMT_COMPILE(L"--sessionId \"{}\" "), idStr); } // The caller is always expected to provide the evaluated profile in the @@ -143,105 +143,104 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation // // else if (ProfileIndex()) // { - // ss << fmt::format(L"profile index: {}, ", ProfileIndex().Value()); + // fmt::format_to(std::back_inserter(str), FMT_COMPILE(L"profile index: {}, "), ProfileIndex().Value()); // } if (!StartingDirectory().empty()) { - ss << fmt::format(L"--startingDirectory {} ", QuoteAndEscapeCommandlineArg(StartingDirectory())); + fmt::format_to(std::back_inserter(str), FMT_COMPILE(L"--startingDirectory {} "), QuoteAndEscapeCommandlineArg(StartingDirectory())); } if (!TabTitle().empty()) { - ss << fmt::format(L"--title {} ", QuoteAndEscapeCommandlineArg(TabTitle())); + fmt::format_to(std::back_inserter(str), FMT_COMPILE(L"--title {} "), QuoteAndEscapeCommandlineArg(TabTitle())); } if (TabColor()) { const til::color tabColor{ TabColor().Value() }; - ss << fmt::format(L"--tabColor \"{}\" ", tabColor.ToHexString(true)); + fmt::format_to(std::back_inserter(str), FMT_COMPILE(L"--tabColor \"{}\" "), tabColor.ToHexString(true)); } if (SuppressApplicationTitle()) { if (SuppressApplicationTitle().Value()) { - ss << fmt::format(L"--suppressApplicationTitle "); + str.append(L"--suppressApplicationTitle "); } else { - ss << fmt::format(L"--useApplicationTitle "); + str.append(L"--useApplicationTitle "); } } if (!ColorScheme().empty()) { - ss << fmt::format(L"--colorScheme {} ", QuoteAndEscapeCommandlineArg(ColorScheme())); + fmt::format_to(std::back_inserter(str), FMT_COMPILE(L"--colorScheme {} "), QuoteAndEscapeCommandlineArg(ColorScheme())); } if (!Commandline().empty()) { - ss << fmt::format(L"-- \"{}\" ", Commandline()); + fmt::format_to(std::back_inserter(str), FMT_COMPILE(L"-- \"{}\" "), Commandline()); } - auto s = ss.str(); - if (s.empty()) + if (str.empty()) { return {}; } // Chop off the last " " - return winrt::hstring{ s.substr(0, s.size() - 1) }; + str.resize(str.size() - 1); + return winrt::hstring{ str }; } winrt::hstring CopyTextArgs::GenerateName() const { - std::wstringstream ss; + std::wstring str; if (SingleLine()) { - ss << RS_(L"CopyTextAsSingleLineCommandKey").c_str(); + str.append(RS_(L"CopyTextAsSingleLineCommandKey")); } else { - ss << RS_(L"CopyTextCommandKey").c_str(); + str.append(RS_(L"CopyTextCommandKey")); } if (!DismissSelection()) { - ss << L", dismissSelection: false"; + str.append(L", dismissSelection: false"); } if (CopyFormatting()) { - ss << L", copyFormatting: "; + str.append(L", copyFormatting: "); if (CopyFormatting().Value() == CopyFormat::All) { - ss << L"all, "; + str.append(L"all, "); } else if (CopyFormatting().Value() == static_cast(0)) { - ss << L"none, "; + str.append(L"none, "); } else { if (WI_IsFlagSet(CopyFormatting().Value(), CopyFormat::HTML)) { - ss << L"html, "; + str.append(L"html, "); } if (WI_IsFlagSet(CopyFormatting().Value(), CopyFormat::RTF)) { - ss << L"rtf, "; + str.append(L"rtf, "); } } - // Chop off the last "," - auto result = ss.str(); - return winrt::hstring{ result.substr(0, result.size() - 2) }; + // Chop off the last ", " + str.resize(str.size() - 2); } - return winrt::hstring{ ss.str() }; + return winrt::hstring{ str }; } winrt::hstring NewTabArgs::GenerateName() const @@ -257,7 +256,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation return RS_(L"NewTabCommandKey"); } return winrt::hstring{ - fmt::format(L"{}, {}", RS_(L"NewTabCommandKey"), newTerminalArgsStr) + fmt::format(FMT_COMPILE(L"{}, {}"), RS_(L"NewTabCommandKey"), newTerminalArgsStr) }; } @@ -273,11 +272,11 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation return RS_(L"MovePaneToNewWindowCommandKey"); } return winrt::hstring{ - fmt::format(L"{}, window:{}, tab index:{}", RS_(L"MovePaneCommandKey"), Window(), TabIndex()) + fmt::format(FMT_COMPILE(L"{}, window:{}, tab index:{}"), RS_(L"MovePaneCommandKey"), Window(), TabIndex()) }; } return winrt::hstring{ - fmt::format(L"{}, tab index:{}", RS_(L"MovePaneCommandKey"), TabIndex()) + fmt::format(FMT_COMPILE(L"{}, tab index:{}"), RS_(L"MovePaneCommandKey"), TabIndex()) }; } @@ -289,7 +288,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation } return winrt::hstring{ - fmt::format(L"{}, index:{}", RS_(L"SwitchToTabCommandKey"), TabIndex()) + fmt::format(FMT_COMPILE(L"{}, index:{}"), RS_(L"SwitchToTabCommandKey"), TabIndex()) }; } @@ -311,10 +310,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation directionString = RS_(L"DirectionDown"); break; } - return winrt::hstring{ - fmt::format(std::wstring_view(RS_(L"ResizePaneWithArgCommandKey")), - directionString) - }; + return winrt::hstring{ RS_fmt(L"ResizePaneWithArgCommandKey", directionString) }; } winrt::hstring MoveFocusArgs::GenerateName() const @@ -348,10 +344,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation return RS_(L"MoveFocusChildPane"); } - return winrt::hstring{ - fmt::format(std::wstring_view(RS_(L"MoveFocusWithArgCommandKey")), - directionString) - }; + return winrt::hstring{ RS_fmt(L"MoveFocusWithArgCommandKey", directionString) }; } winrt::hstring SwapPaneArgs::GenerateName() const @@ -381,10 +374,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation return RS_(L"SwapPaneFirstPane"); } - return winrt::hstring{ - fmt::format(std::wstring_view(RS_(L"SwapPaneWithArgCommandKey")), - directionString) - }; + return winrt::hstring{ RS_fmt(L"SwapPaneWithArgCommandKey", directionString) }; } winrt::hstring AdjustFontSizeArgs::GenerateName() const @@ -395,19 +385,11 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation // * Decrease font size, amount: {delta}" if (Delta() < 0) { - return Delta() == -1 ? RS_(L"DecreaseFontSizeCommandKey") : - winrt::hstring{ - fmt::format(std::wstring_view(RS_(L"DecreaseFontSizeWithAmountCommandKey")), - -Delta()) - }; + return Delta() == -1 ? RS_(L"DecreaseFontSizeCommandKey") : winrt::hstring{ RS_fmt(L"DecreaseFontSizeWithAmountCommandKey", -Delta()) }; } else { - return Delta() == 1 ? RS_(L"IncreaseFontSizeCommandKey") : - winrt::hstring{ - fmt::format(std::wstring_view(RS_(L"IncreaseFontSizeWithAmountCommandKey")), - Delta()) - }; + return Delta() == 1 ? RS_(L"IncreaseFontSizeCommandKey") : winrt::hstring{ RS_fmt(L"IncreaseFontSizeWithAmountCommandKey", Delta()) }; } } @@ -416,8 +398,8 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation // The string will be similar to the following: // * "Send Input: ...input..." - auto escapedInput = til::visualize_control_codes(Input()); - auto name = fmt::format(std::wstring_view(RS_(L"SendInputCommandKey")), escapedInput); + const auto escapedInput = til::visualize_control_codes(Input()); + const auto name = RS_fmt(L"SendInputCommandKey", escapedInput); return winrt::hstring{ name }; } @@ -432,38 +414,38 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation // If this is a "duplicate pane" action, then the new terminal arguments // will be omitted (as they're unused) - std::wstringstream ss; + std::wstring str; if (SplitMode() == SplitType::Duplicate) { - ss << std::wstring_view(RS_(L"DuplicatePaneCommandKey")); + str.append(RS_(L"DuplicatePaneCommandKey")); } else { - ss << std::wstring_view(RS_(L"SplitPaneCommandKey")); + str.append(RS_(L"SplitPaneCommandKey")); } - ss << L", "; + str.append(L", "); // This text is intentionally _not_ localized, to attempt to mirror the // exact syntax that the property would have in JSON. switch (SplitDirection()) { case SplitDirection::Up: - ss << L"split: up, "; + str.append(L"split: up, "); break; case SplitDirection::Right: - ss << L"split: right, "; + str.append(L"split: right, "); break; case SplitDirection::Down: - ss << L"split: down, "; + str.append(L"split: down, "); break; case SplitDirection::Left: - ss << L"split: left, "; + str.append(L"split: left, "); break; } if (SplitSize() != .5f) { - ss << L"size: " << (SplitSize() * 100) << L"%, "; + fmt::format_to(std::back_inserter(str), FMT_COMPILE(L"size: {:.2f}%, "), SplitSize() * 100); } winrt::hstring newTerminalArgsStr; @@ -474,13 +456,13 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation if (SplitMode() != SplitType::Duplicate && !newTerminalArgsStr.empty()) { - ss << newTerminalArgsStr.c_str(); - ss << L", "; + str.append(newTerminalArgsStr); + str.append(L", "); } // Chop off the last ", " - auto s = ss.str(); - return winrt::hstring{ s.substr(0, s.size() - 2) }; + str.resize(str.size() - 2); + return winrt::hstring{ str }; } winrt::hstring OpenSettingsArgs::GenerateName() const @@ -531,10 +513,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation // "Set color scheme to "{_SchemeName}"" if (!SchemeName().empty()) { - return winrt::hstring{ - fmt::format(std::wstring_view(RS_(L"SetColorSchemeCommandKey")), - SchemeName().c_str()) - }; + return winrt::hstring{ RS_fmt(L"SetColorSchemeCommandKey", SchemeName()) }; } return {}; } @@ -546,10 +525,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation if (TabColor()) { til::color tabColor{ TabColor().Value() }; - return winrt::hstring{ - fmt::format(std::wstring_view(RS_(L"SetTabColorCommandKey")), - tabColor.ToHexString(true)) - }; + return winrt::hstring{ RS_fmt(L"SetTabColorCommandKey", tabColor.ToHexString(true)) }; } return RS_(L"ResetTabColorCommandKey"); @@ -561,10 +537,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation // "Reset tab title" if (!Title().empty()) { - return winrt::hstring{ - fmt::format(std::wstring_view(RS_(L"RenameTabCommandKey")), - Title().c_str()) - }; + return winrt::hstring{ RS_fmt(L"RenameTabCommandKey", Title()) }; } return RS_(L"ResetTabNameCommandKey"); } @@ -574,10 +547,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation // "Run commandline "{_Commandline}" in this window" if (!Commandline().empty()) { - return winrt::hstring{ - fmt::format(std::wstring_view(RS_(L"ExecuteCommandlineCommandKey")), - Commandline().c_str()) - }; + return winrt::hstring{ RS_fmt(L"ExecuteCommandlineCommandKey", Commandline()) }; } return {}; } @@ -587,10 +557,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation if (Index()) { // "Close tabs other than index {0}" - return winrt::hstring{ - fmt::format(std::wstring_view(RS_(L"CloseOtherTabsCommandKey")), - Index().Value()) - }; + return winrt::hstring{ RS_fmt(L"CloseOtherTabsCommandKey", Index().Value()) }; } return RS_(L"CloseOtherTabsDefaultCommandKey"); } @@ -600,10 +567,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation if (Index()) { // "Close tabs after index {0}" - return winrt::hstring{ - fmt::format(std::wstring_view(RS_(L"CloseTabsAfterCommandKey")), - Index().Value()) - }; + return winrt::hstring{ RS_fmt(L"CloseTabsAfterCommandKey", Index().Value()) }; } return RS_(L"CloseTabsAfterDefaultCommandKey"); } @@ -613,10 +577,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation if (Index()) { // "Close tab at index {0}" - return winrt::hstring{ - fmt::format(std::wstring_view(RS_(L"CloseTabAtIndexCommandKey")), - Index().Value()) - }; + return winrt::hstring{ RS_fmt(L"CloseTabAtIndexCommandKey", Index().Value()) }; } return RS_(L"CloseTabCommandKey"); } @@ -625,10 +586,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation { if (RowsToScroll()) { - return winrt::hstring{ - fmt::format(std::wstring_view(RS_(L"ScrollUpSeveralRowsCommandKey")), - RowsToScroll().Value()) - }; + return winrt::hstring{ RS_fmt(L"ScrollUpSeveralRowsCommandKey", RowsToScroll().Value()) }; } return RS_(L"ScrollUpCommandKey"); } @@ -637,10 +595,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation { if (RowsToScroll()) { - return winrt::hstring{ - fmt::format(std::wstring_view(RS_(L"ScrollDownSeveralRowsCommandKey")), - RowsToScroll().Value()) - }; + return winrt::hstring{ RS_fmt(L"ScrollDownSeveralRowsCommandKey", RowsToScroll().Value()) }; } return RS_(L"ScrollDownCommandKey"); } @@ -666,10 +621,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation { if (Color()) { - return winrt::hstring{ - fmt::format(std::wstring_view(RS_(L"AddMarkWithColorCommandKey")), - til::color{ Color().Value() }.ToHexString(true)) - }; + return winrt::hstring{ RS_fmt(L"AddMarkWithColorCommandKey", til::color{ Color().Value() }.ToHexString(true)) }; } else { @@ -685,10 +637,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation { return RS_(L"MoveTabToNewWindowCommandKey"); } - return winrt::hstring{ - fmt::format(std::wstring_view(RS_(L"MoveTabToWindowCommandKey")), - Window()) - }; + return winrt::hstring{ RS_fmt(L"MoveTabToWindowCommandKey", Window()) }; } winrt::hstring directionString; @@ -701,10 +650,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation directionString = RS_(L"MoveTabDirectionBackward"); break; } - return winrt::hstring{ - fmt::format(std::wstring_view(RS_(L"MoveTabCommandKey")), - directionString) - }; + return winrt::hstring{ RS_fmt(L"MoveTabCommandKey", directionString) }; } winrt::hstring ToggleCommandPaletteArgs::GenerateName() const @@ -718,42 +664,40 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation winrt::hstring SuggestionsArgs::GenerateName() const { - std::wstringstream ss; - ss << RS_(L"SuggestionsCommandKey").c_str(); + std::wstring str; + str.append(RS_(L"SuggestionsCommandKey")); if (UseCommandline()) { - ss << L", useCommandline:true"; + str.append(L", useCommandline:true"); } // All of the source values will leave a trailing ", " that we need to chop later: - ss << L", source: "; + str.append(L", source: "); const auto source = Source(); if (source == SuggestionsSource::All) { - ss << L"all, "; + str.append(L"all, "); } else if (source == static_cast(0)) { - ss << L"none, "; + str.append(L"none, "); } else { if (WI_IsFlagSet(source, SuggestionsSource::Tasks)) { - ss << L"tasks, "; + str.append(L"tasks, "); } if (WI_IsFlagSet(source, SuggestionsSource::CommandHistory)) { - ss << L"commandHistory, "; + str.append(L"commandHistory, "); } } // Chop off the last "," - auto result = ss.str(); - // use `resize`, to avoid duplicating the entire string. (substr doesn't create a view.) - result.resize(result.size() - 2); - return winrt::hstring{ result }; + str.resize(str.size() - 2); + return winrt::hstring{ str }; } winrt::hstring FindMatchArgs::GenerateName() const @@ -780,9 +724,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation { return RS_(L"NewWindowCommandKey"); } - return winrt::hstring{ - fmt::format(L"{}, {}", RS_(L"NewWindowCommandKey"), newTerminalArgsStr) - }; + return winrt::hstring{ fmt::format(FMT_COMPILE(L"{}, {}"), RS_(L"NewWindowCommandKey"), newTerminalArgsStr) }; } winrt::hstring PrevTabArgs::GenerateName() const @@ -793,7 +735,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation } const auto mode = SwitcherMode().Value() == TabSwitcherMode::MostRecentlyUsed ? L"most recently used" : L"in order"; - return winrt::hstring(fmt::format(L"{}, {}", RS_(L"PrevTabCommandKey"), mode)); + return winrt::hstring(fmt::format(FMT_COMPILE(L"{}, {}"), RS_(L"PrevTabCommandKey"), mode)); } winrt::hstring NextTabArgs::GenerateName() const @@ -804,7 +746,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation } const auto mode = SwitcherMode().Value() == TabSwitcherMode::MostRecentlyUsed ? L"most recently used" : L"in order"; - return winrt::hstring(fmt::format(L"{}, {}", RS_(L"NextTabCommandKey"), mode)); + return winrt::hstring(fmt::format(FMT_COMPILE(L"{}, {}"), RS_(L"NextTabCommandKey"), mode)); } winrt::hstring RenameWindowArgs::GenerateName() const @@ -813,10 +755,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation // "Clear window name" if (!Name().empty()) { - return winrt::hstring{ - fmt::format(std::wstring_view(RS_(L"RenameWindowCommandKey")), - Name().c_str()) - }; + return winrt::hstring{ RS_fmt(L"RenameWindowCommandKey", Name()) }; } return RS_(L"ResetWindowNameCommandKey"); } @@ -832,10 +771,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation try { - return winrt::hstring{ - fmt::format(std::wstring_view(RS_(L"SearchForTextCommandKey")), - Windows::Foundation::Uri(QueryUrl()).Domain().c_str()) - }; + return winrt::hstring{ RS_fmt(L"SearchForTextCommandKey", Windows::Foundation::Uri(QueryUrl()).Domain()) }; } CATCH_LOG(); @@ -854,26 +790,22 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation return RS_(L"QuakeModeCommandKey"); } - std::wstringstream ss; - ss << std::wstring_view(RS_(L"GlobalSummonCommandKey")); + std::wstring str{ RS_(L"GlobalSummonCommandKey") }; // "Summon the Terminal window" // "Summon the Terminal window, name:\"{_Name}\"" if (!Name().empty()) { - ss << L", name: "; - ss << std::wstring_view(Name()); + str.append(L", name: "); + str.append(Name()); } - return winrt::hstring{ ss.str() }; + return winrt::hstring{ str }; } winrt::hstring FocusPaneArgs::GenerateName() const { // "Focus pane {Id}" - return winrt::hstring{ - fmt::format(std::wstring_view(RS_(L"FocusPaneCommandKey")), - Id()) - }; + return winrt::hstring{ RS_fmt(L"FocusPaneCommandKey", Id()) }; } winrt::hstring ExportBufferArgs::GenerateName() const @@ -881,10 +813,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation if (!Path().empty()) { // "Export text to {path}" - return winrt::hstring{ - fmt::format(std::wstring_view(RS_(L"ExportBufferToPathCommandKey")), - Path()) - }; + return winrt::hstring{ RS_fmt(L"ExportBufferToPathCommandKey", Path()) }; } else { @@ -924,27 +853,18 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation if (Opacity() >= 0) { // "Increase background opacity by {Opacity}%" - return winrt::hstring{ - fmt::format(std::wstring_view(RS_(L"IncreaseOpacityCommandKey")), - Opacity()) - }; + return winrt::hstring{ RS_fmt(L"IncreaseOpacityCommandKey", Opacity()) }; } else { // "Decrease background opacity by {Opacity}%" - return winrt::hstring{ - fmt::format(std::wstring_view(RS_(L"DecreaseOpacityCommandKey")), - Opacity()) - }; + return winrt::hstring{ RS_fmt(L"DecreaseOpacityCommandKey", Opacity()) }; } } else { // "Set background opacity to {Opacity}%" - return winrt::hstring{ - fmt::format(std::wstring_view(RS_(L"AdjustOpacityCommandKey")), - Opacity()) - }; + return winrt::hstring{ RS_fmt(L"AdjustOpacityCommandKey", Opacity()) }; } } @@ -952,21 +872,19 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation { if (Feature_SaveSnippet::IsEnabled()) { - std::wstringstream ss; - - ss << RS_(L"SaveSnippetNamePrefix").c_str() << L" commandline: " << Commandline().c_str(); + auto str = fmt::format(FMT_COMPILE(L"{} commandline: {}"), RS_(L"SaveSnippetNamePrefix"), Commandline()); if (!Name().empty()) { - ss << L", name: " << Name().c_str(); + fmt::format_to(std::back_inserter(str), FMT_COMPILE(L", name: {}"), Name()); } if (!KeyChord().empty()) { - ss << L", keyChord " << KeyChord().c_str(); + fmt::format_to(std::back_inserter(str), FMT_COMPILE(L", keyChord {}"), KeyChord()); } - return winrt::hstring{ ss.str() }; + return winrt::hstring{ str }; } return {}; } @@ -1039,7 +957,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation auto matchModeStr = winrt::hstring{}; if (MatchMode() == Core::MatchMode::All) { - matchModeStr = fmt::format(L", {}", RS_(L"ColorSelection_allMatches")); // ", all matches" + matchModeStr = fmt::format(FMT_COMPILE(L", {}"), RS_(L"ColorSelection_allMatches")); // ", all matches" } const auto foreground = Foreground(); @@ -1058,31 +976,23 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation if (foreground && backgroundIsBoring) { - const auto str = RS_(L"ColorSelection_fg_action"); // "Color selection, foreground: {0}{1}" - return winrt::hstring{ - fmt::format(std::wstring_view{ str }, fgStr, matchModeStr) - }; + // "Color selection, foreground: {0}{1}" + return winrt::hstring{ RS_fmt(L"ColorSelection_fg_action", fgStr, matchModeStr) }; } else if (background && foregroundIsBoring) { - const auto str = RS_(L"ColorSelection_bg_action"); // "Color selection, background: {0}{1}" - return winrt::hstring{ - fmt::format(std::wstring_view{ str }, bgStr, matchModeStr) - }; + // "Color selection, background: {0}{1}" + return winrt::hstring{ RS_fmt(L"ColorSelection_bg_action", bgStr, matchModeStr) }; } else if (foreground && background) { - const auto str = RS_(L"ColorSelection_fg_bg_action"); // "Color selection, foreground: {0}, background: {1}{2}" - return winrt::hstring{ - fmt::format(std::wstring_view{ str }, fgStr, bgStr, matchModeStr) - }; + // "Color selection, foreground: {0}, background: {1}{2}" + return winrt::hstring{ RS_fmt(L"ColorSelection_fg_bg_action", fgStr, bgStr, matchModeStr) }; } else { - const auto str = RS_(L"ColorSelection_default_action"); // "Color selection, (default foreground/background){0}" - return winrt::hstring{ - fmt::format(std::wstring_view{ str }, matchModeStr) - }; + // "Color selection, (default foreground/background){0}" + return winrt::hstring{ RS_fmt(L"ColorSelection_default_action", matchModeStr) }; } } diff --git a/src/cascadia/TerminalSettingsModel/ActionMap.cpp b/src/cascadia/TerminalSettingsModel/ActionMap.cpp index 5d298457c7..3d80220f79 100644 --- a/src/cascadia/TerminalSettingsModel/ActionMap.cpp +++ b/src/cascadia/TerminalSettingsModel/ActionMap.cpp @@ -845,7 +845,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation // UI easier. const auto escapedInput = til::visualize_nonspace_control_codes(std::wstring{ inputString }); - const auto name = fmt::format(std::wstring_view(RS_(L"SendInputCommandKey")), escapedInput); + const auto name = RS_fmt(L"SendInputCommandKey", escapedInput); copy->Name(winrt::hstring{ name }); } diff --git a/src/cascadia/TerminalSettingsModel/CascadiaSettings.cpp b/src/cascadia/TerminalSettingsModel/CascadiaSettings.cpp index 8607a811a7..5a9fb2a736 100644 --- a/src/cascadia/TerminalSettingsModel/CascadiaSettings.cpp +++ b/src/cascadia/TerminalSettingsModel/CascadiaSettings.cpp @@ -224,7 +224,7 @@ Model::Profile CascadiaSettings::CreateNewProfile() for (uint32_t candidateIndex = 0, count = _allProfiles.Size() + 1; candidateIndex < count; candidateIndex++) { // There is a theoretical unsigned integer wraparound, which is OK - newName = fmt::format(L"Profile {}", count + candidateIndex); + newName = fmt::format(FMT_COMPILE(L"Profile {}"), count + candidateIndex); if (std::none_of(begin(_allProfiles), end(_allProfiles), [&](auto&& profile) { return profile.Name() == newName; })) { break; @@ -265,7 +265,7 @@ Model::Profile CascadiaSettings::DuplicateProfile(const Model::Profile& source) { THROW_HR_IF_NULL(E_INVALIDARG, source); - auto newName = fmt::format(L"{} ({})", source.Name(), RS_(L"CopySuffix")); + auto newName = fmt::format(FMT_COMPILE(L"{} ({})"), source.Name(), RS_(L"CopySuffix")); // Check if this name already exists and if so, append a number for (uint32_t candidateIndex = 0, count = _allProfiles.Size() + 1; candidateIndex < count; ++candidateIndex) @@ -275,7 +275,7 @@ Model::Profile CascadiaSettings::DuplicateProfile(const Model::Profile& source) break; } // There is a theoretical unsigned integer wraparound, which is OK - newName = fmt::format(L"{} ({} {})", source.Name(), RS_(L"CopySuffix"), candidateIndex + 2); + newName = fmt::format(FMT_COMPILE(L"{} ({} {})"), source.Name(), RS_(L"CopySuffix"), candidateIndex + 2); } const auto duplicated = _createNewProfile(newName); diff --git a/src/cascadia/TerminalSettingsModel/CascadiaSettingsSerialization.cpp b/src/cascadia/TerminalSettingsModel/CascadiaSettingsSerialization.cpp index abb6caa0e1..3d576f6060 100644 --- a/src/cascadia/TerminalSettingsModel/CascadiaSettingsSerialization.cpp +++ b/src/cascadia/TerminalSettingsModel/CascadiaSettingsSerialization.cpp @@ -556,12 +556,12 @@ void SettingsLoader::_rethrowSerializationExceptionWithLocationInfo(const JsonUt const auto [line, column] = _lineAndColumnFromPosition(settingsString, static_cast(e.jsonValue.getOffsetStart())); fmt::memory_buffer msg; - fmt::format_to(msg, "* Line {}, Column {}", line, column); + fmt::format_to(std::back_inserter(msg), "* Line {}, Column {}", line, column); if (e.key) { - fmt::format_to(msg, " ({})", *e.key); + fmt::format_to(std::back_inserter(msg), " ({})", *e.key); } - fmt::format_to(msg, "\n Have: {}\n Expected: {}\0", jsonValueAsString, e.expectedType); + fmt::format_to(std::back_inserter(msg), "\n Have: {}\n Expected: {}\0", jsonValueAsString, e.expectedType); throw SettingsTypedDeserializationException{ msg.data() }; } @@ -1246,7 +1246,7 @@ winrt::hstring CascadiaSettings::_calculateHash(std::string_view settings, const { const auto fileHash = til::hash(settings); const ULARGE_INTEGER fileTime{ lastWriteTime.dwLowDateTime, lastWriteTime.dwHighDateTime }; - const auto hash = fmt::format(L"{:016x}-{:016x}", fileHash, fileTime.QuadPart); + const auto hash = fmt::format(FMT_COMPILE(L"{:016x}-{:016x}"), fileHash, fileTime.QuadPart); return winrt::hstring{ hash }; } diff --git a/src/cascadia/TerminalSettingsModel/Command.cpp b/src/cascadia/TerminalSettingsModel/Command.cpp index ac66d188b9..730d883463 100644 --- a/src/cascadia/TerminalSettingsModel/Command.cpp +++ b/src/cascadia/TerminalSettingsModel/Command.cpp @@ -727,7 +727,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation continue; } auto args = winrt::make_self( - winrt::hstring{ fmt::format(L"{}{}{}", cdText, backspaces, line) }); + winrt::hstring{ fmt::format(FMT_COMPILE(L"{}{}{}"), cdText, backspaces, line) }); Model::ActionAndArgs actionAndArgs{ ShortcutAction::SendInput, *args }; diff --git a/src/cascadia/TerminalSettingsModel/DefaultTerminal.cpp b/src/cascadia/TerminalSettingsModel/DefaultTerminal.cpp index 754ed7cbd8..6a6b903c6f 100644 --- a/src/cascadia/TerminalSettingsModel/DefaultTerminal.cpp +++ b/src/cascadia/TerminalSettingsModel/DefaultTerminal.cpp @@ -37,9 +37,7 @@ winrt::hstring DefaultTerminal::Version() const return winrt::hstring{}; } - fmt::wmemory_buffer buffer; - fmt::format_to(buffer, L"{}.{}.{}.{}", version.major, version.minor, version.build, version.revision); - return winrt::hstring{ buffer.data(), gsl::narrow_cast(buffer.size()) }; + return winrt::hstring{ fmt::format(FMT_COMPILE(L"{}.{}.{}.{}"), version.major, version.minor, version.build, version.revision) }; } winrt::hstring DefaultTerminal::Author() const diff --git a/src/cascadia/TerminalSettingsModel/DefaultTerminal.h b/src/cascadia/TerminalSettingsModel/DefaultTerminal.h index f8cebcafde..6aabae137d 100644 --- a/src/cascadia/TerminalSettingsModel/DefaultTerminal.h +++ b/src/cascadia/TerminalSettingsModel/DefaultTerminal.h @@ -30,7 +30,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation hstring ToString() { - return hstring{ fmt::format(L"{}, {}, {}", Name(), Author(), Version()) }; + return hstring{ fmt::format(FMT_COMPILE(L"{}, {}, {}"), Name(), Author(), Version()) }; } hstring Name() const; diff --git a/src/cascadia/WinRTUtils/inc/LibraryResources.h b/src/cascadia/WinRTUtils/inc/LibraryResources.h index 2c6f4de1aa..56a0b1b5e1 100644 --- a/src/cascadia/WinRTUtils/inc/LibraryResources.h +++ b/src/cascadia/WinRTUtils/inc/LibraryResources.h @@ -69,3 +69,12 @@ namespace Microsoft::Console::Utils winrt::hstring GetLibraryResourceString(const std::wstring_view key); bool HasLibraryResourceWithName(const std::wstring_view key); + +#define RS_fmt(x, ...) RS_fmt_impl(USES_RESOURCE(x), __VA_ARGS__) + +template +std::wstring RS_fmt_impl(std::wstring_view key, Args&&... args) +{ + const auto format = GetLibraryResourceString(key); + return fmt::format(fmt::runtime(std::wstring_view{ format }), std::forward(args)...); +} diff --git a/src/cascadia/WinRTUtils/inc/WtExeUtils.h b/src/cascadia/WinRTUtils/inc/WtExeUtils.h index 306af685e1..eddda66d09 100644 --- a/src/cascadia/WinRTUtils/inc/WtExeUtils.h +++ b/src/cascadia/WinRTUtils/inc/WtExeUtils.h @@ -109,7 +109,7 @@ _TIL_INLINEPREFIX const std::wstring& GetWtExePath() // Method Description: // - Quotes and escapes the given string so that it can be used as a command-line arg. // - e.g. given `\";foo\` will return `"\\\"\;foo\\"` so that the caller can construct a command-line -// using something such as `fmt::format(L"wt --title {}", QuoteAndQuoteAndEscapeCommandlineArg(TabTitle()))`. +// using something such as `fmt::format(FMT_COMPILE(L"wt --title {}"), QuoteAndQuoteAndEscapeCommandlineArg(TabTitle()))`. // Arguments: // - arg - the command-line argument to quote and escape. // Return Value: diff --git a/src/cascadia/WindowsTerminal/AppHost.cpp b/src/cascadia/WindowsTerminal/AppHost.cpp index bdf4fbfd53..6ecd065f46 100644 --- a/src/cascadia/WindowsTerminal/AppHost.cpp +++ b/src/cascadia/WindowsTerminal/AppHost.cpp @@ -239,7 +239,7 @@ void AppHost::_HandleSessionRestore(const bool startedForContent) // Create new windows for each of the other saved layouts. for (const auto size = layouts.Size(); startIdx < size; startIdx += 1) { - auto newWindowArgs = fmt::format(L"{0} -w new -s {1}", args.Commandline()[0], startIdx); + auto newWindowArgs = fmt::format(FMT_COMPILE(L"{} -w new -s {}"), args.Commandline()[0], startIdx); STARTUPINFO si; memset(&si, 0, sizeof(si)); diff --git a/src/cascadia/WindowsTerminal/WindowEmperor.cpp b/src/cascadia/WindowsTerminal/WindowEmperor.cpp index 1e78e721fd..0891cf451a 100644 --- a/src/cascadia/WindowsTerminal/WindowEmperor.cpp +++ b/src/cascadia/WindowsTerminal/WindowEmperor.cpp @@ -595,7 +595,7 @@ static winrt::fire_and_forget _createNewTerminalWindow(Settings::Model::GlobalSu // If we weren't given a name, then just use new to force the window to be // unnamed. winrt::hstring cmdline{ - fmt::format(L"-w {}", + fmt::format(FMT_COMPILE(L"-w {}"), args.Name().empty() ? L"new" : args.Name()) }; diff --git a/src/cascadia/inc/cppwinrt_utils.h b/src/cascadia/inc/cppwinrt_utils.h index fa1575d32a..0f35d6eefc 100644 --- a/src/cascadia/inc/cppwinrt_utils.h +++ b/src/cascadia/inc/cppwinrt_utils.h @@ -20,7 +20,7 @@ Revision History: template<> struct fmt::formatter : fmt::formatter { - auto format(const winrt::hstring& str, auto& ctx) + auto format(const winrt::hstring& str, auto& ctx) const { return fmt::formatter::format({ str.data(), str.size() }, ctx); } diff --git a/src/inc/LibraryIncludes.h b/src/inc/LibraryIncludes.h index 41b74ccab9..a80e351ffe 100644 --- a/src/inc/LibraryIncludes.h +++ b/src/inc/LibraryIncludes.h @@ -83,8 +83,11 @@ #include // {fmt}, a C++20-compatible formatting library -#include +#pragma warning(push) +#pragma warning(disable: 4702) // unreachable code #include +#include +#pragma warning(pop) #define USE_INTERVAL_TREE_NAMESPACE #include diff --git a/src/renderer/atlas/pch.h b/src/renderer/atlas/pch.h index f06a26c494..240af13275 100644 --- a/src/renderer/atlas/pch.h +++ b/src/renderer/atlas/pch.h @@ -6,16 +6,12 @@ #define NOMINMAX #define WIN32_LEAN_AND_MEAN -#include #include +#include #include #include #include -#include #include -#include -#include -#include #include #include @@ -32,9 +28,7 @@ #include #include #include -#include #include -#include // Chromium Numerics (safe math) #pragma warning(push) @@ -44,8 +38,10 @@ #pragma warning(pop) // {fmt}, a C++20-compatible formatting library -#include +#pragma warning(push) +#pragma warning(disable : 4702) // unreachable code #include +#include +#pragma warning(pop) #include -#include diff --git a/src/terminal/adapter/DispatchTypes.hpp b/src/terminal/adapter/DispatchTypes.hpp index cb8adee015..4db898d1a8 100644 --- a/src/terminal/adapter/DispatchTypes.hpp +++ b/src/terminal/adapter/DispatchTypes.hpp @@ -28,7 +28,7 @@ namespace Microsoft::Console::VirtualTerminal return _value; } - constexpr const std::string_view ToString() const + constexpr const char* ToString() const { return &_string[0]; } @@ -693,3 +693,31 @@ namespace Microsoft::Console::VirtualTerminal::DispatchTypes constexpr VTInt s_sDECCOLMResetColumns = 80; } + +#pragma warning(push) +#pragma warning(disable : 26429) // Symbol 'in' is never tested for nullness, it can be marked as not_null (f.23). +#pragma warning(disable : 26481) // Don't use pointer arithmetic. Use span instead (bounds.1). + +template +struct fmt::formatter +{ + constexpr auto parse(auto& ctx) + { + return ctx.begin(); + } + + constexpr auto format(const Microsoft::Console::VirtualTerminal::VTID& p, auto& ctx) const + { + auto in = p.ToString(); + auto out = ctx.out(); + + for (; *in; ++in, ++out) + { + *out = *in; + } + + return out; + } +}; + +#pragma warning(pop) diff --git a/src/terminal/adapter/adaptDispatch.cpp b/src/terminal/adapter/adaptDispatch.cpp index 2ff55fb7b2..8bc5631e9a 100644 --- a/src/terminal/adapter/adaptDispatch.cpp +++ b/src/terminal/adapter/adaptDispatch.cpp @@ -4077,7 +4077,7 @@ bool AdaptDispatch::RequestUserPreferenceCharset() { const auto size = _termOutput.GetUserPreferenceCharsetSize(); const auto id = _termOutput.GetUserPreferenceCharsetId(); - _api.ReturnResponse(fmt::format(FMT_COMPILE(L"\033P{}!u{}\033\\"), (size == 96 ? 1 : 0), id.ToString())); + _api.ReturnResponse(fmt::format(FMT_COMPILE(L"\033P{}!u{}\033\\"), (size == 96 ? 1 : 0), id)); return true; } @@ -4632,10 +4632,10 @@ void AdaptDispatch::_ReportCursorInformation() leftSetNumber, rightSetNumber, charsetSizes, - charset0.ToString(), - charset1.ToString(), - charset2.ToString(), - charset3.ToString()); + charset0, + charset1, + charset2, + charset3); _api.ReturnResponse({ response.data(), response.size() }); } diff --git a/src/types/UiaTracing.cpp b/src/types/UiaTracing.cpp index 80bc99d166..cc31b273e6 100644 --- a/src/types/UiaTracing.cpp +++ b/src/types/UiaTracing.cpp @@ -663,7 +663,7 @@ void UiaTracing::TextProvider::RangeFromPoint(const ScreenInfoUiaProviderBase& s if (TraceLoggingProviderEnabled(g_UiaProviderTraceProvider, WINEVENT_LEVEL_VERBOSE, TIL_KEYWORD_TRACE)) { static constexpr auto getPoint = [](const UiaPoint& point) { - return fmt::format(FMT_COMPILE(L"{},{}"), (float)point.x, (float)point.y); + return fmt::format(FMT_COMPILE(L"{},{}"), (int)point.x, (int)point.y); }; TraceLoggingWrite( diff --git a/src/types/utils.cpp b/src/types/utils.cpp index 1c65c2f889..0d099f7ad2 100644 --- a/src/types/utils.cpp +++ b/src/types/utils.cpp @@ -959,7 +959,7 @@ std::tuple Utils::MangleStartingDirectoryForWSL(std: break; // just bail out. } - if (!til::equals_insensitive_ascii(executablePath.parent_path().c_str(), systemDirectory)) + if (!til::equals_insensitive_ascii(executablePath.parent_path().native(), systemDirectory)) { break; // it wasn't in system32! } diff --git a/vcpkg.json b/vcpkg.json index 23b33e9de6..bd610a805e 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -16,7 +16,7 @@ "overrides": [ { "name": "fmt", - "version": "7.1.3" + "version": "11.0.2" }, { "name": "ms-gsl", @@ -31,5 +31,5 @@ "version": "2.4.2" } ], - "builtin-baseline": "2fd62b5d878104f4092af80533923bfe2bba2ee0" + "builtin-baseline": "fe1cde61e971d53c9687cf9a46308f8f55da19fa" }