Skip to content

Commit ec88b32

Browse files
committed
add dynamic profile generators
1 parent f5f6345 commit ec88b32

File tree

5 files changed

+70
-18
lines changed

5 files changed

+70
-18
lines changed

src/cascadia/TerminalSettingsEditor/Extensions.cpp

+16-5
Original file line numberDiff line numberDiff line change
@@ -111,14 +111,25 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
111111
_extensionSources.clear();
112112
_CurrentExtensionSource.clear();
113113

114-
std::vector<Editor::FragmentExtensionViewModel> fragmentExtensions;
115-
fragmentExtensions.reserve(settings.FragmentExtensions().Size());
114+
std::vector<Model::FragmentSettings> extensions;
115+
extensions.reserve(settings.FragmentExtensions().Size() + settings.DynamicProfileGenerators().Size());
116+
for (auto ext : settings.FragmentExtensions())
117+
{
118+
extensions.push_back(ext);
119+
}
120+
for (auto ext : settings.DynamicProfileGenerators())
121+
{
122+
extensions.push_back(ext);
123+
}
124+
125+
std::vector<Editor::FragmentExtensionViewModel> extensionVMs;
126+
extensionVMs.reserve(extensions.size());
116127

117128
// these vectors track components all extensions successfully added
118129
std::vector<Editor::FragmentProfileViewModel> profilesModifiedTotal;
119130
std::vector<Editor::FragmentProfileViewModel> profilesAddedTotal;
120131
std::vector<Editor::FragmentColorSchemeViewModel> colorSchemesAddedTotal;
121-
for (const auto&& fragExt : settings.FragmentExtensions())
132+
for (const auto& fragExt : extensions)
122133
{
123134
const auto extensionEnabled = GetExtensionState(fragExt.Source());
124135

@@ -173,10 +184,10 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
173184
}
174185

175186
_extensionSources.insert(fragExt.Source());
176-
fragmentExtensions.push_back(winrt::make<FragmentExtensionViewModel>(fragExt, currentProfilesModified, currentProfilesAdded, currentColorSchemesAdded));
187+
extensionVMs.push_back(winrt::make<FragmentExtensionViewModel>(fragExt, currentProfilesModified, currentProfilesAdded, currentColorSchemesAdded));
177188
}
178189

179-
_fragmentExtensions = single_threaded_observable_vector<Editor::FragmentExtensionViewModel>(std::move(fragmentExtensions));
190+
_fragmentExtensions = single_threaded_observable_vector<Editor::FragmentExtensionViewModel>(std::move(extensionVMs));
180191
_profilesModifiedView = single_threaded_observable_vector<Editor::FragmentProfileViewModel>(std::move(profilesModifiedTotal));
181192
_profilesAddedView = single_threaded_observable_vector<Editor::FragmentProfileViewModel>(std::move(profilesAddedTotal));
182193
_colorSchemesAddedView = single_threaded_observable_vector<Editor::FragmentColorSchemeViewModel>(std::move(colorSchemesAddedTotal));

src/cascadia/TerminalSettingsModel/CascadiaSettings.cpp

+16
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,17 @@ Model::CascadiaSettings CascadiaSettings::Copy() const
124124
}
125125
settings->_fragmentExtensions = winrt::single_threaded_vector(std::move(fragmentExtensions));
126126
}
127+
128+
// copy dynamic profile generators
129+
{
130+
std::vector<Model::FragmentSettings> dynamicProfileGenerators;
131+
dynamicProfileGenerators.reserve(_dynamicProfileGeneratorExtensions.Size());
132+
for (const auto& fragment : _dynamicProfileGeneratorExtensions)
133+
{
134+
dynamicProfileGenerators.emplace_back(get_self<FragmentSettings>(fragment)->Copy());
135+
}
136+
settings->_dynamicProfileGeneratorExtensions = winrt::single_threaded_vector(std::move(dynamicProfileGenerators));
137+
}
127138
}
128139

129140
// load errors
@@ -220,6 +231,11 @@ IVectorView<Model::FragmentSettings> CascadiaSettings::FragmentExtensions() cons
220231
return _fragmentExtensions.GetView();
221232
}
222233

234+
IVectorView<Model::FragmentSettings> CascadiaSettings::DynamicProfileGenerators() const noexcept
235+
{
236+
return _dynamicProfileGeneratorExtensions.GetView();
237+
}
238+
223239
// Method Description:
224240
// - Returns the globally configured keybindings
225241
// Arguments:

src/cascadia/TerminalSettingsModel/CascadiaSettings.h

+3
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
7474
ParsedSettings inboxSettings;
7575
ParsedSettings userSettings;
7676
std::vector<Model::FragmentSettings> fragmentExtensions;
77+
std::vector<Model::FragmentSettings> dynamicProfileGeneratorExtensions;
7778
bool duplicateProfile = false;
7879

7980
private:
@@ -132,6 +133,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
132133
winrt::Windows::Foundation::Collections::IObservableVector<Model::Profile> ActiveProfiles() const noexcept;
133134
Model::ActionMap ActionMap() const noexcept;
134135
winrt::Windows::Foundation::Collections::IVectorView<Model::FragmentSettings> FragmentExtensions() const noexcept;
136+
winrt::Windows::Foundation::Collections::IVectorView<Model::FragmentSettings> DynamicProfileGenerators() const noexcept;
135137
void WriteSettingsToDisk();
136138
Json::Value ToJson() const;
137139
Model::Profile ProfileDefaults() const;
@@ -190,6 +192,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
190192
winrt::Windows::Foundation::Collections::IObservableVector<Model::Profile> _allProfiles = winrt::single_threaded_observable_vector<Model::Profile>();
191193
winrt::Windows::Foundation::Collections::IObservableVector<Model::Profile> _activeProfiles = winrt::single_threaded_observable_vector<Model::Profile>();
192194
winrt::Windows::Foundation::Collections::IVector<Model::FragmentSettings> _fragmentExtensions = winrt::single_threaded_vector<Model::FragmentSettings>();
195+
winrt::Windows::Foundation::Collections::IVector<Model::FragmentSettings> _dynamicProfileGeneratorExtensions = winrt::single_threaded_vector<Model::FragmentSettings>();
193196
std::set<std::string> _themesChangeLog{};
194197

195198
// load errors

src/cascadia/TerminalSettingsModel/CascadiaSettings.idl

+1
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ namespace Microsoft.Terminal.Settings.Model
4545

4646
ActionMap ActionMap { get; };
4747
Windows.Foundation.Collections.IVectorView<FragmentSettings> FragmentExtensions { get; };
48+
Windows.Foundation.Collections.IVectorView<FragmentSettings> DynamicProfileGenerators { get; };
4849

4950
IVectorView<SettingsLoadWarnings> Warnings { get; };
5051
Windows.Foundation.IReference<SettingsLoadErrors> GetLoadingError { get; };

src/cascadia/TerminalSettingsModel/CascadiaSettingsSerialization.cpp

+34-13
Original file line numberDiff line numberDiff line change
@@ -991,31 +991,51 @@ bool SettingsLoader::_addOrMergeUserColorScheme(const winrt::com_ptr<implementat
991991
void SettingsLoader::_executeGenerator(const IDynamicProfileGenerator& generator)
992992
{
993993
const auto generatorNamespace = generator.GetNamespace();
994-
if (_ignoredNamespaces.contains(generatorNamespace))
995-
{
996-
return;
997-
}
998-
999-
const auto previousSize = inboxSettings.profiles.size();
1000-
994+
std::vector<winrt::com_ptr<implementation::Profile>> generatedProfiles;
1001995
try
1002996
{
1003-
generator.GenerateProfiles(inboxSettings.profiles);
997+
generator.GenerateProfiles(generatedProfiles);
1004998
}
1005999
CATCH_LOG_MSG("Dynamic Profile Namespace: \"%.*s\"", gsl::narrow<int>(generatorNamespace.size()), generatorNamespace.data())
10061000

1001+
// These are needed for the FragmentSettings object
1002+
std::vector<Model::FragmentProfileEntry> profileEntries;
1003+
Json::Value profilesListJson{ Json::ValueType::arrayValue };
1004+
Json::StreamWriterBuilder styledWriter;
1005+
styledWriter["indentation"] = " ";
1006+
10071007
// If the generator produced some profiles we're going to give them default attributes.
10081008
// By setting the Origin/Source/etc. here, we deduplicate some code and ensure they aren't missing accidentally.
1009-
if (inboxSettings.profiles.size() > previousSize)
1009+
const winrt::hstring source{ generatorNamespace };
1010+
for (const auto& profile : generatedProfiles)
10101011
{
1011-
const winrt::hstring source{ generatorNamespace };
1012+
profile->Origin(OriginTag::Generated);
1013+
profile->Source(source);
1014+
1015+
const auto profileJson = profile->ToJson();
1016+
profilesListJson.append(profileJson);
1017+
profileEntries.push_back(winrt::make<FragmentProfileEntry>(profile->Guid(), hstring{ til::u8u16(Json::writeString(styledWriter, profileJson)) }));
1018+
}
10121019

1013-
for (const auto& profile : std::span(inboxSettings.profiles).subspan(previousSize))
1020+
if (!_ignoredNamespaces.contains(generatorNamespace))
1021+
{
1022+
// Add generated profiles to the user settings
1023+
for (auto& profile : generatedProfiles)
10141024
{
1015-
profile->Origin(OriginTag::Generated);
1016-
profile->Source(source);
1025+
inboxSettings.profiles.push_back(profile);
10171026
}
10181027
}
1028+
1029+
// Manually construct the JSON for the FragmentSettings object
1030+
Json::Value json{ Json::ValueType::objectValue };
1031+
json[JsonKey(ProfilesKey)] = profilesListJson;
1032+
1033+
auto generatorExtension = winrt::make_self<FragmentSettings>(hstring{ generatorNamespace }, hstring{ til::u8u16(Json::writeString(styledWriter, json)) }, hstring{ L"settings.json" }, FragmentScope::Machine);
1034+
for (const auto& entry : profileEntries)
1035+
{
1036+
generatorExtension->NewProfiles().Append(entry);
1037+
}
1038+
dynamicProfileGeneratorExtensions.emplace_back(*generatorExtension);
10191039
}
10201040

10211041
// Method Description:
@@ -1308,6 +1328,7 @@ CascadiaSettings::CascadiaSettings(SettingsLoader&& loader) :
13081328
_warnings = winrt::single_threaded_vector(std::move(warnings));
13091329
_themesChangeLog = std::move(loader.userSettings.themesChangeLog);
13101330
_fragmentExtensions = winrt::single_threaded_vector(std::move(loader.fragmentExtensions));
1331+
_dynamicProfileGeneratorExtensions = winrt::single_threaded_vector(std::move(loader.dynamicProfileGeneratorExtensions));
13111332

13121333
_resolveDefaultProfile();
13131334
_resolveNewTabMenuProfiles();

0 commit comments

Comments
 (0)