mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-07 19:57:07 +02:00
PowerRename: Add Lookbehind (#7571)
* Add boost-regex library * If enabled use boost lib for regex Add property `_useBoostLib` to `CPowerRenameRegEx`. If enabled for replacements with regular expressions the Boost Library is used instead of the Standard Library. * Extend signatures to create RegEx with Boost Extend create and constructor singatures of `CPowerRenameRegEx` with an option to enable (or disabled, which is default) the Boost Library. * Verify Lookbehind fails with STD library To verify that the boost library is disabled as expected, check if a lookbehind fails. * Add Unit tests for RegEx with Boost Add unit tests to verify regex replacement with Boost Library. They are copied and adapted from the Standard Library tests. * Improve verify capturing groups test with Boost It is possible to use a capturing group followed by numbers as replacement if the group number is enclosed in curly braces. Added test cases based on the Standard Library tests. * Add useBoostLib to settings interface * Get library option from settings object * Reduce signatures of RegEx by "useBoost" Remove the parameter added in 19105cf, as it became obsolete. * Settings: Read useBoostLib from JSON file * Add UseBoostLib Option to UI * Boost Lib label states the regex syntax difference * Fix Regex with Boost Lib tests - Do not load settings another time in CPowerRenameRegEx ctor - Set flag correctly in standard library regex tests * Add "lookbehind" to dictionary * change Library to lowercase, and also add a comment As suggested by @enricogior. Co-authored-by: Enrico Giordani <enricogior@users.noreply.github.com> * Change Library to lowercase and add a comment As suggested by @enricogior. Co-authored-by: Enrico Giordani <enricogior@users.noreply.github.com>
This commit is contained in:
@@ -189,6 +189,8 @@
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets')" />
|
||||
<Import Project="..\..\..\..\packages\boost.1.72.0.0\build\boost.targets" Condition="Exists('..\..\..\..\packages\boost.1.72.0.0\build\boost.targets')" />
|
||||
<Import Project="..\..\..\..\packages\boost_regex-vc142.1.72.0.0\build\boost_regex-vc142.targets" Condition="Exists('..\..\..\..\packages\boost_regex-vc142.1.72.0.0\build\boost_regex-vc142.targets')" />
|
||||
</ImportGroup>
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
@@ -196,5 +198,7 @@
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\boost.1.72.0.0\build\boost.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\boost.1.72.0.0\build\boost.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\boost_regex-vc142.1.72.0.0\build\boost_regex-vc142.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\boost_regex-vc142.1.72.0.0\build\boost_regex-vc142.targets'))" />
|
||||
</Target>
|
||||
</Project>
|
||||
@@ -1,8 +1,10 @@
|
||||
#include "pch.h"
|
||||
#include "PowerRenameRegEx.h"
|
||||
#include "Settings.h"
|
||||
#include <regex>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <boost/regex.hpp>
|
||||
|
||||
|
||||
using namespace std;
|
||||
@@ -177,6 +179,8 @@ CPowerRenameRegEx::CPowerRenameRegEx() :
|
||||
// Init to empty strings
|
||||
SHStrDup(L"", &m_searchTerm);
|
||||
SHStrDup(L"", &m_replaceTerm);
|
||||
|
||||
_useBoostLib = CSettingsInstance().GetUseBoostLib();
|
||||
}
|
||||
|
||||
CPowerRenameRegEx::~CPowerRenameRegEx()
|
||||
@@ -206,14 +210,29 @@ HRESULT CPowerRenameRegEx::Replace(_In_ PCWSTR source, _Outptr_ PWSTR* result)
|
||||
|
||||
if (m_flags & UseRegularExpressions)
|
||||
{
|
||||
std::wregex pattern(m_searchTerm, (!(m_flags & CaseSensitive)) ? regex_constants::icase | regex_constants::ECMAScript : regex_constants::ECMAScript);
|
||||
if (m_flags & MatchAllOccurences)
|
||||
if (_useBoostLib)
|
||||
{
|
||||
res = regex_replace(wstring(source), pattern, replaceTerm);
|
||||
boost::wregex pattern(m_searchTerm, (!(m_flags & CaseSensitive)) ? boost::regex::icase | boost::regex::ECMAScript : boost::regex::ECMAScript);
|
||||
if (m_flags & MatchAllOccurences)
|
||||
{
|
||||
res = boost::regex_replace(wstring(source), pattern, replaceTerm);
|
||||
}
|
||||
else
|
||||
{
|
||||
res = boost::regex_replace(wstring(source), pattern, replaceTerm, boost::regex_constants::format_first_only);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
res = regex_replace(wstring(source), pattern, replaceTerm, regex_constants::format_first_only);
|
||||
std::wregex pattern(m_searchTerm, (!(m_flags & CaseSensitive)) ? regex_constants::icase | regex_constants::ECMAScript : regex_constants::ECMAScript);
|
||||
if (m_flags & MatchAllOccurences)
|
||||
{
|
||||
res = regex_replace(wstring(source), pattern, replaceTerm);
|
||||
}
|
||||
else
|
||||
{
|
||||
res = regex_replace(wstring(source), pattern, replaceTerm, regex_constants::format_first_only);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -39,6 +39,7 @@ protected:
|
||||
|
||||
size_t _Find(std::wstring data, std::wstring toSearch, bool caseInsensitive, size_t pos);
|
||||
|
||||
bool _useBoostLib = false;
|
||||
DWORD m_flags = DEFAULT_FLAGS;
|
||||
PWSTR m_searchTerm = nullptr;
|
||||
PWSTR m_replaceTerm = nullptr;
|
||||
|
||||
@@ -31,6 +31,7 @@ namespace
|
||||
const wchar_t c_mruEnabled[] = L"MRUEnabled";
|
||||
const wchar_t c_mruList[] = L"MRUList";
|
||||
const wchar_t c_insertionIdx[] = L"InsertionIdx";
|
||||
const wchar_t c_useBoostLib[] = L"UseBoostLib";
|
||||
|
||||
unsigned int GetRegNumber(const std::wstring& valueName, unsigned int defaultValue)
|
||||
{
|
||||
@@ -414,6 +415,7 @@ void CSettings::Save()
|
||||
jsonData.SetNamedValue(c_maxMRUSize, json::value(settings.maxMRUSize));
|
||||
jsonData.SetNamedValue(c_searchText, json::value(settings.searchText));
|
||||
jsonData.SetNamedValue(c_replaceText, json::value(settings.replaceText));
|
||||
jsonData.SetNamedValue(c_useBoostLib, json::value(settings.useBoostLib));
|
||||
|
||||
json::to_file(jsonFilePath, jsonData);
|
||||
GetSystemTimeAsFileTime(&lastLoadedTime);
|
||||
@@ -457,6 +459,7 @@ void CSettings::MigrateFromRegistry()
|
||||
settings.flags = GetRegNumber(c_flags, 0);
|
||||
settings.searchText = GetRegString(c_searchText, L"");
|
||||
settings.replaceText = GetRegString(c_replaceText, L"");
|
||||
settings.useBoostLib = false; // Never existed in registry, disabled by default.
|
||||
}
|
||||
|
||||
void CSettings::ParseJson()
|
||||
@@ -499,6 +502,10 @@ void CSettings::ParseJson()
|
||||
{
|
||||
settings.replaceText = jsonSettings.GetNamedString(c_replaceText);
|
||||
}
|
||||
if (json::has(jsonSettings, c_useBoostLib, json::JsonValueType::Boolean))
|
||||
{
|
||||
settings.useBoostLib = jsonSettings.GetNamedBoolean(c_useBoostLib);
|
||||
}
|
||||
}
|
||||
catch (const winrt::hresult_error&) { }
|
||||
}
|
||||
|
||||
@@ -51,6 +51,16 @@ public:
|
||||
settings.persistState = persistState;
|
||||
}
|
||||
|
||||
inline bool GetUseBoostLib() const
|
||||
{
|
||||
return settings.useBoostLib;
|
||||
}
|
||||
|
||||
inline void SetUseBoostLib(bool useBoostLib)
|
||||
{
|
||||
settings.useBoostLib = useBoostLib;
|
||||
}
|
||||
|
||||
inline bool GetMRUEnabled() const
|
||||
{
|
||||
return settings.MRUEnabled;
|
||||
@@ -114,6 +124,7 @@ private:
|
||||
bool showIconOnMenu{ true };
|
||||
bool extendedContextMenuOnly{ false }; // Disabled by default.
|
||||
bool persistState{ true };
|
||||
bool useBoostLib{ false }; // Disabled by default.
|
||||
bool MRUEnabled{ true };
|
||||
unsigned int maxMRUSize{ 10 };
|
||||
unsigned int flags{ 0 };
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="boost" version="1.72.0.0" targetFramework="native" />
|
||||
<package id="boost_regex-vc142" version="1.72.0.0" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.200729.8" targetFramework="native" />
|
||||
</packages>
|
||||
@@ -85,5 +85,6 @@ void Trace::SettingsChanged() noexcept
|
||||
TraceLoggingBoolean(CSettingsInstance().GetPersistState(), "PersistState"),
|
||||
TraceLoggingBoolean(CSettingsInstance().GetMRUEnabled(), "IsMRUEnabled"),
|
||||
TraceLoggingUInt64(CSettingsInstance().GetMaxMRUSize(), "MaxMRUSize"),
|
||||
TraceLoggingBoolean(CSettingsInstance().GetUseBoostLib(), "UseBoostLib"),
|
||||
TraceLoggingUInt64(CSettingsInstance().GetFlags(), "Flags"));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user